Add missing Z suffix when formating execution time#503
Merged
albert-kunushevci merged 1 commit intoArcenox-co:mainfrom Jan 18, 2026
Merged
Add missing Z suffix when formating execution time#503albert-kunushevci merged 1 commit intoArcenox-co:mainfrom
Z suffix when formating execution time#503albert-kunushevci merged 1 commit intoArcenox-co:mainfrom
Conversation
Contributor
Author
|
I kept this PR small and focused on the bug fix. A few things related to date utilities that could be refactored:
|
Contributor
Author
|
@arcenox is it possible to have a patch release? I would like to have the dashboard authentication fixes, they're blocking me. |
Collaborator
|
@jods4 I will make a release this Sunday. |
Contributor
Author
|
Perfect, thanks! |
albert-kunushevci
approved these changes
Jan 18, 2026
Contributor
Author
|
@arcenox No pressure, I just need to adjust my own plans: |
albert-kunushevci
added a commit
that referenced
this pull request
Mar 15, 2026
* Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test to not require live Redis connection The test was resolving the service provider which triggered an actual Redis connection attempt. Changed to check the service descriptor instead, which validates registration without needing a running server. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 15, 2026
* Fixed the issue with dead node release * Fixed the scheduler to handle inline tasks and to not create deadlock on threads of TickerQ * fixed the window time of picking tasks * Fixed the task cancellation issue * fixed the scheduler to show real time threads active * updated version for release * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#377) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#379) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#383) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Updated PR to push net9 * fixed merge conflicts * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#387) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#389) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#392) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#394) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * 🔄 Sync main branch changes to net9 (#400) * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files * Fixed the issue with .net app net9 versions --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#402) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#404) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#406) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#420) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#421) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#424) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#425) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * 🔄 Sync main branch changes to net9 (#431) * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files * Added reference to TickerQ from Test csproj --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#435) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#452) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#467) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#489) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#491) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#493) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#495) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#506) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#529) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#531) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#538) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#536) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#533) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Fix #521: Set explicit C# 13 language version for .NET 9 (#547) Set LangVersion to 13.0 in Directory.Build.props for deterministic builds and remove the per-project LangVersion override from TickerQ.csproj. C# 13 is the latest language version compatible with .NET 9. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#545) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#552) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#553) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#555) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#565) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#563) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#561) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#558) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#560) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#568) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * fix .net9 * fix build prop * fix * fix * fix * stable release along with hub. * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#577) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * fix dashboard and conflicts * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#583) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#608) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#613) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#601) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#597) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#595) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#592) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#588) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files * Sync changes from main to net9 - Applied recent commits, updated versions & framework, preserved .csproj files (#625) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Fix DotNetVersion range for net9 — was incorrectly set to [10.0.0,11.0.0) (#626) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Sync changes from main to net9 (#630) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync main → net9 (#634) * Sync changes from main to net9 * Add IsEnabled support to sync-excluded EF Core files for net9 Add IsEnabled to ForCronTickerExpressions mapping and filter disabled cron tickers in GetAllCronTickerExpressions. These files are excluded from git sync and need manual updates per target framework. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Sync changes from main to net9 (#637) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#640) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#643) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#646) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#649) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#653) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#655) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#660) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#662) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#664) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#667) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#671) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Fix test project versions and PR workflow on net9 branch - Add tests/Directory.Build.props with net9 TargetFramework and DotNetVersion - Replace hardcoded versions with $(DotNetVersion) in test csproj files - Add missing Microsoft.AspNetCore.TestHost package for DashboardPathBaseTests - Add EF Core test project to PR workflow build and test steps Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Sync changes from main to net9 (#674) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#678) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * Sync changes from main to net9 (#679) * Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test to not require live Redis connection The test was resolving the service provider which triggered an actual Redis connection attempt. Changed to check the service descriptor instead, which validates registration without needing a running server. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Arbër Maksuti <arbermaksuti01@gmail.com> Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 21, 2026
* Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply version-specific overrides for net9 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 21, 2026
* Fixed the issue with dead node release * Fixed the scheduler to handle inline tasks and to not create deadlock on threads of TickerQ * fixed the window time of picking tasks * Fixed the task cancellation issue * fixed the scheduler to show real time threads active * Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply version-specific overrides for net8 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 21, 2026
* Fixed the issue with dead node release * Fixed the scheduler to handle inline tasks and to not create deadlock on threads of TickerQ * fixed the window time of picking tasks * Fixed the task cancellation issue * fixed the scheduler to show real time threads active * Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723) Clear host-level endpoint routing state in MapPathBaseAware before entering the dashboard branch pipeline. When host-level Map*() calls (e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing, the EndpointRoutingMiddleware may set an endpoint on the HttpContext. The branch's own UseRouting() then skips evaluation (it short-circuits when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket requests to hit the wrong endpoint and return 405. The fix calls SetEndpoint(null) and clears RouteValues when the dashboard base path matches, ensuring the branch's routing middleware re-evaluates against dashboard endpoints. Closes #456 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721) Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the IsEnabled property in CronTickerConfigurations. The former emits DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904). HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server, PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core still sends explicit false values instead of deferring to the DB default. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Switch build and sync workflows to trigger on release - build.yml: trigger on release publish instead of push to main/net8/net9 - sync-version-branches.yml: trigger on release publish instead of push to main - Both keep workflow_dispatch as manual fallback - Updated Discord notification for release context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add test step to release build workflow Tests run before packaging — if tests fail, no NuGet packages are published. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Source Link and symbol package support (#743) * Add Source Link and symbol package support - Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping - Generate .snupkg symbol packages alongside .nupkg - Enable deterministic builds and CI build flag - Embed untracked sources for complete debugging experience Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder - Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename) - Remove src/src.sln (replaced by TickerQ.slnx on main) - Move hub projects to dedicated /hub/ folder in TickerQ.slnx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add src/src.sln to sync-exclude to protect it on net8/net9 branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date/time display for Windows timezone IDs (#717) (#719) Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA format (e.g. "America/New_York") before sending to the frontend, so Intl.DateTimeFormat can correctly render dates in the configured scheduler timezone. Also add defensive fallback in the frontend formatDate() for invalid timezone IDs, and Windows timezone ID pattern matching in getDateFormatRegion() for correct US/EU date format selection. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Skip TickerQ initialization in design-time tools (#712) (#763) * Skip TickerQ initialization when running inside design-time tools (#712) Build-time tools like dotnet-getdocument (used by Microsoft.Extensions.ApiDescription.Server for OpenAPI generation) invoke Program.Main to build the host, which triggers UseTickerQ → InitializeTickerQ → SeedDefinedCronTickers. This causes database queries in a context where no valid connection string exists, crashing the build. Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool entry assemblies and short-circuits InitializeTickerQ before any DB-touching or background service initialization occurs. Closes #712 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712) Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based approach: move all I/O-bound initialization (function discovery, DB seeding, external provider startup) from inline UseTickerQ into a dedicated TickerQInitializerHostedService that runs during host.StartAsync(). Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but never start it, so the hosted service naturally never runs — no heuristics needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix TickerFunctionProvider Build() race condition and add startup validation (#764) - Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests) don't overwrite a populated FrozenDictionary with an empty one (fixes #705) - Initialize static FrozenDictionary fields to .Empty instead of null to prevent NullReferenceException when UseTickerQ() is not called - Add IsBuilt flag to distinguish "UseTickerQ() not called" from "no [TickerFunction] methods found" - Add TickerQStartupValidator IHostedService that warns at startup when UseTickerQ() is missing or no ticker functions are registered - Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 10.2.3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build pipeline: restore only build targets, not samples The sample project uses PackageReference with $(Version) which resolves to the version being built. Restoring the full solution fails because the package isn't published yet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch Sample.WorkerService from PackageReference to ProjectReference Fixes sync build failures on net8/net9 branches where $(Version) resolved to a version that doesn't exist on NuGet yet. All samples now consistently use ProjectReference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply version-specific overrides for net8 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 21, 2026
* Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723) Clear host-level endpoint routing state in MapPathBaseAware before entering the dashboard branch pipeline. When host-level Map*() calls (e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing, the EndpointRoutingMiddleware may set an endpoint on the HttpContext. The branch's own UseRouting() then skips evaluation (it short-circuits when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket requests to hit the wrong endpoint and return 405. The fix calls SetEndpoint(null) and clears RouteValues when the dashboard base path matches, ensuring the branch's routing middleware re-evaluates against dashboard endpoints. Closes #456 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721) Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the IsEnabled property in CronTickerConfigurations. The former emits DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904). HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server, PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core still sends explicit false values instead of deferring to the DB default. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Switch build and sync workflows to trigger on release - build.yml: trigger on release publish instead of push to main/net8/net9 - sync-version-branches.yml: trigger on release publish instead of push to main - Both keep workflow_dispatch as manual fallback - Updated Discord notification for release context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add test step to release build workflow Tests run before packaging — if tests fail, no NuGet packages are published. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Source Link and symbol package support (#743) * Add Source Link and symbol package support - Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping - Generate .snupkg symbol packages alongside .nupkg - Enable deterministic builds and CI build flag - Embed untracked sources for complete debugging experience Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder - Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename) - Remove src/src.sln (replaced by TickerQ.slnx on main) - Move hub projects to dedicated /hub/ folder in TickerQ.slnx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add src/src.sln to sync-exclude to protect it on net8/net9 branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date/time display for Windows timezone IDs (#717) (#719) Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA format (e.g. "America/New_York") before sending to the frontend, so Intl.DateTimeFormat can correctly render dates in the configured scheduler timezone. Also add defensive fallback in the frontend formatDate() for invalid timezone IDs, and Windows timezone ID pattern matching in getDateFormatRegion() for correct US/EU date format selection. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Skip TickerQ initialization in design-time tools (#712) (#763) * Skip TickerQ initialization when running inside design-time tools (#712) Build-time tools like dotnet-getdocument (used by Microsoft.Extensions.ApiDescription.Server for OpenAPI generation) invoke Program.Main to build the host, which triggers UseTickerQ → InitializeTickerQ → SeedDefinedCronTickers. This causes database queries in a context where no valid connection string exists, crashing the build. Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool entry assemblies and short-circuits InitializeTickerQ before any DB-touching or background service initialization occurs. Closes #712 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712) Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based approach: move all I/O-bound initialization (function discovery, DB seeding, external provider startup) from inline UseTickerQ into a dedicated TickerQInitializerHostedService that runs during host.StartAsync(). Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but never start it, so the hosted service naturally never runs — no heuristics needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix TickerFunctionProvider Build() race condition and add startup validation (#764) - Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests) don't overwrite a populated FrozenDictionary with an empty one (fixes #705) - Initialize static FrozenDictionary fields to .Empty instead of null to prevent NullReferenceException when UseTickerQ() is not called - Add IsBuilt flag to distinguish "UseTickerQ() not called" from "no [TickerFunction] methods found" - Add TickerQStartupValidator IHostedService that warns at startup when UseTickerQ() is missing or no ticker functions are registered - Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 10.2.3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build pipeline: restore only build targets, not samples The sample project uses PackageReference with $(Version) which resolves to the version being built. Restoring the full solution fails because the package isn't published yet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch Sample.WorkerService from PackageReference to ProjectReference Fixes sync build failures on net8/net9 branches where $(Version) resolved to a version that doesn't exist on NuGet yet. All samples now consistently use ProjectReference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply version-specific overrides for net9 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 21, 2026
* Fixed the issue with dead node release * Fixed the scheduler to handle inline tasks and to not create deadlock on threads of TickerQ * fixed the window time of picking tasks * Fixed the task cancellation issue * fixed the scheduler to show real time threads active * Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723) Clear host-level endpoint routing state in MapPathBaseAware before entering the dashboard branch pipeline. When host-level Map*() calls (e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing, the EndpointRoutingMiddleware may set an endpoint on the HttpContext. The branch's own UseRouting() then skips evaluation (it short-circuits when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket requests to hit the wrong endpoint and return 405. The fix calls SetEndpoint(null) and clears RouteValues when the dashboard base path matches, ensuring the branch's routing middleware re-evaluates against dashboard endpoints. Closes #456 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721) Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the IsEnabled property in CronTickerConfigurations. The former emits DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904). HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server, PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core still sends explicit false values instead of deferring to the DB default. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Switch build and sync workflows to trigger on release - build.yml: trigger on release publish instead of push to main/net8/net9 - sync-version-branches.yml: trigger on release publish instead of push to main - Both keep workflow_dispatch as manual fallback - Updated Discord notification for release context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add test step to release build workflow Tests run before packaging — if tests fail, no NuGet packages are published. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Source Link and symbol package support (#743) * Add Source Link and symbol package support - Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping - Generate .snupkg symbol packages alongside .nupkg - Enable deterministic builds and CI build flag - Embed untracked sources for complete debugging experience Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder - Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename) - Remove src/src.sln (replaced by TickerQ.slnx on main) - Move hub projects to dedicated /hub/ folder in TickerQ.slnx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add src/src.sln to sync-exclude to protect it on net8/net9 branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date/time display for Windows timezone IDs (#717) (#719) Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA format (e.g. "America/New_York") before sending to the frontend, so Intl.DateTimeFormat can correctly render dates in the configured scheduler timezone. Also add defensive fallback in the frontend formatDate() for invalid timezone IDs, and Windows timezone ID pattern matching in getDateFormatRegion() for correct US/EU date format selection. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Skip TickerQ initialization in design-time tools (#712) (#763) * Skip TickerQ initialization when running inside design-time tools (#712) Build-time tools like dotnet-getdocument (used by Microsoft.Extensions.ApiDescription.Server for OpenAPI generation) invoke Program.Main to build the host, which triggers UseTickerQ → InitializeTickerQ → SeedDefinedCronTickers. This causes database queries in a context where no valid connection string exists, crashing the build. Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool entry assemblies and short-circuits InitializeTickerQ before any DB-touching or background service initialization occurs. Closes #712 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712) Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based approach: move all I/O-bound initialization (function discovery, DB seeding, external provider startup) from inline UseTickerQ into a dedicated TickerQInitializerHostedService that runs during host.StartAsync(). Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but never start it, so the hosted service naturally never runs — no heuristics needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix TickerFunctionProvider Build() race condition and add startup validation (#764) - Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests) don't overwrite a populated FrozenDictionary with an empty one (fixes #705) - Initialize static FrozenDictionary fields to .Empty instead of null to prevent NullReferenceException when UseTickerQ() is not called - Add IsBuilt flag to distinguish "UseTickerQ() not called" from "no [TickerFunction] methods found" - Add TickerQStartupValidator IHostedService that warns at startup when UseTickerQ() is missing or no ticker functions are registered - Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 10.2.3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build pipeline: restore only build targets, not samples The sample project uses PackageReference with $(Version) which resolves to the version being built. Restoring the full solution fails because the package isn't published yet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch Sample.WorkerService from PackageReference to ProjectReference Fixes sync build failures on net8/net9 branches where $(Version) resolved to a version that doesn't exist on NuGet yet. All samples now consistently use ProjectReference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply version-specific overrides for net8 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 21, 2026
* Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723) Clear host-level endpoint routing state in MapPathBaseAware before entering the dashboard branch pipeline. When host-level Map*() calls (e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing, the EndpointRoutingMiddleware may set an endpoint on the HttpContext. The branch's own UseRouting() then skips evaluation (it short-circuits when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket requests to hit the wrong endpoint and return 405. The fix calls SetEndpoint(null) and clears RouteValues when the dashboard base path matches, ensuring the branch's routing middleware re-evaluates against dashboard endpoints. Closes #456 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721) Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the IsEnabled property in CronTickerConfigurations. The former emits DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904). HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server, PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core still sends explicit false values instead of deferring to the DB default. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Switch build and sync workflows to trigger on release - build.yml: trigger on release publish instead of push to main/net8/net9 - sync-version-branches.yml: trigger on release publish instead of push to main - Both keep workflow_dispatch as manual fallback - Updated Discord notification for release context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add test step to release build workflow Tests run before packaging — if tests fail, no NuGet packages are published. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Source Link and symbol package support (#743) * Add Source Link and symbol package support - Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping - Generate .snupkg symbol packages alongside .nupkg - Enable deterministic builds and CI build flag - Embed untracked sources for complete debugging experience Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder - Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename) - Remove src/src.sln (replaced by TickerQ.slnx on main) - Move hub projects to dedicated /hub/ folder in TickerQ.slnx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add src/src.sln to sync-exclude to protect it on net8/net9 branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date/time display for Windows timezone IDs (#717) (#719) Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA format (e.g. "America/New_York") before sending to the frontend, so Intl.DateTimeFormat can correctly render dates in the configured scheduler timezone. Also add defensive fallback in the frontend formatDate() for invalid timezone IDs, and Windows timezone ID pattern matching in getDateFormatRegion() for correct US/EU date format selection. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Skip TickerQ initialization in design-time tools (#712) (#763) * Skip TickerQ initialization when running inside design-time tools (#712) Build-time tools like dotnet-getdocument (used by Microsoft.Extensions.ApiDescription.Server for OpenAPI generation) invoke Program.Main to build the host, which triggers UseTickerQ → InitializeTickerQ → SeedDefinedCronTickers. This causes database queries in a context where no valid connection string exists, crashing the build. Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool entry assemblies and short-circuits InitializeTickerQ before any DB-touching or background service initialization occurs. Closes #712 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712) Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based approach: move all I/O-bound initialization (function discovery, DB seeding, external provider startup) from inline UseTickerQ into a dedicated TickerQInitializerHostedService that runs during host.StartAsync(). Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but never start it, so the hosted service naturally never runs — no heuristics needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix TickerFunctionProvider Build() race condition and add startup validation (#764) - Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests) don't overwrite a populated FrozenDictionary with an empty one (fixes #705) - Initialize static FrozenDictionary fields to .Empty instead of null to prevent NullReferenceException when UseTickerQ() is not called - Add IsBuilt flag to distinguish "UseTickerQ() not called" from "no [TickerFunction] methods found" - Add TickerQStartupValidator IHostedService that warns at startup when UseTickerQ() is missing or no ticker functions are registered - Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 10.2.3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build pipeline: restore only build targets, not samples The sample project uses PackageReference with $(Version) which resolves to the version being built. Restoring the full solution fails because the package isn't published yet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch Sample.WorkerService from PackageReference to ProjectReference Fixes sync build failures on net8/net9 branches where $(Version) resolved to a version that doesn't exist on NuGet yet. All samples now consistently use ProjectReference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply version-specific overrides for net9 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 21, 2026
* Fixed the issue with dead node release * Fixed the scheduler to handle inline tasks and to not create deadlock on threads of TickerQ * fixed the window time of picking tasks * Fixed the task cancellation issue * fixed the scheduler to show real time threads active * Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723) Clear host-level endpoint routing state in MapPathBaseAware before entering the dashboard branch pipeline. When host-level Map*() calls (e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing, the EndpointRoutingMiddleware may set an endpoint on the HttpContext. The branch's own UseRouting() then skips evaluation (it short-circuits when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket requests to hit the wrong endpoint and return 405. The fix calls SetEndpoint(null) and clears RouteValues when the dashboard base path matches, ensuring the branch's routing middleware re-evaluates against dashboard endpoints. Closes #456 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721) Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the IsEnabled property in CronTickerConfigurations. The former emits DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904). HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server, PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core still sends explicit false values instead of deferring to the DB default. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Switch build and sync workflows to trigger on release - build.yml: trigger on release publish instead of push to main/net8/net9 - sync-version-branches.yml: trigger on release publish instead of push to main - Both keep workflow_dispatch as manual fallback - Updated Discord notification for release context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add test step to release build workflow Tests run before packaging — if tests fail, no NuGet packages are published. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Source Link and symbol package support (#743) * Add Source Link and symbol package support - Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping - Generate .snupkg symbol packages alongside .nupkg - Enable deterministic builds and CI build flag - Embed untracked sources for complete debugging experience Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder - Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename) - Remove src/src.sln (replaced by TickerQ.slnx on main) - Move hub projects to dedicated /hub/ folder in TickerQ.slnx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add src/src.sln to sync-exclude to protect it on net8/net9 branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date/time display for Windows timezone IDs (#717) (#719) Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA format (e.g. "America/New_York") before sending to the frontend, so Intl.DateTimeFormat can correctly render dates in the configured scheduler timezone. Also add defensive fallback in the frontend formatDate() for invalid timezone IDs, and Windows timezone ID pattern matching in getDateFormatRegion() for correct US/EU date format selection. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Skip TickerQ initialization in design-time tools (#712) (#763) * Skip TickerQ initialization when running inside design-time tools (#712) Build-time tools like dotnet-getdocument (used by Microsoft.Extensions.ApiDescription.Server for OpenAPI generation) invoke Program.Main to build the host, which triggers UseTickerQ → InitializeTickerQ → SeedDefinedCronTickers. This causes database queries in a context where no valid connection string exists, crashing the build. Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool entry assemblies and short-circuits InitializeTickerQ before any DB-touching or background service initialization occurs. Closes #712 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712) Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based approach: move all I/O-bound initialization (function discovery, DB seeding, external provider startup) from inline UseTickerQ into a dedicated TickerQInitializerHostedService that runs during host.StartAsync(). Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but never start it, so the hosted service naturally never runs — no heuristics needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix TickerFunctionProvider Build() race condition and add startup validation (#764) - Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests) don't overwrite a populated FrozenDictionary with an empty one (fixes #705) - Initialize static FrozenDictionary fields to .Empty instead of null to prevent NullReferenceException when UseTickerQ() is not called - Add IsBuilt flag to distinguish "UseTickerQ() not called" from "no [TickerFunction] methods found" - Add TickerQStartupValidator IHostedService that warns at startup when UseTickerQ() is missing or no ticker functions are registered - Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 10.2.3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build pipeline: restore only build targets, not samples The sample project uses PackageReference with $(Version) which resolves to the version being built. Restoring the full solution fails because the package isn't published yet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch Sample.WorkerService from PackageReference to ProjectReference Fixes sync build failures on net8/net9 branches where $(Version) resolved to a version that doesn't exist on NuGet yet. All samples now consistently use ProjectReference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add UseAuthorization() to dashboard branch pipeline for Host auth (#408) (#773) When WithHostAuthentication() is configured, dashboard endpoints use RequireAuthorization() metadata. ASP.NET Core's EndpointMiddleware throws InvalidOperationException if no AuthorizationMiddleware exists between UseRouting() and UseEndpoints(). The host app's UseAuthorization() does not propagate into Map() branches, so the dashboard branch needs its own. Closes #408 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Bump version to 10.2.4 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply version-specific overrides for net8 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 21, 2026
* Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723) Clear host-level endpoint routing state in MapPathBaseAware before entering the dashboard branch pipeline. When host-level Map*() calls (e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing, the EndpointRoutingMiddleware may set an endpoint on the HttpContext. The branch's own UseRouting() then skips evaluation (it short-circuits when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket requests to hit the wrong endpoint and return 405. The fix calls SetEndpoint(null) and clears RouteValues when the dashboard base path matches, ensuring the branch's routing middleware re-evaluates against dashboard endpoints. Closes #456 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721) Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the IsEnabled property in CronTickerConfigurations. The former emits DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904). HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server, PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core still sends explicit false values instead of deferring to the DB default. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Switch build and sync workflows to trigger on release - build.yml: trigger on release publish instead of push to main/net8/net9 - sync-version-branches.yml: trigger on release publish instead of push to main - Both keep workflow_dispatch as manual fallback - Updated Discord notification for release context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add test step to release build workflow Tests run before packaging — if tests fail, no NuGet packages are published. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Source Link and symbol package support (#743) * Add Source Link and symbol package support - Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping - Generate .snupkg symbol packages alongside .nupkg - Enable deterministic builds and CI build flag - Embed untracked sources for complete debugging experience Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder - Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename) - Remove src/src.sln (replaced by TickerQ.slnx on main) - Move hub projects to dedicated /hub/ folder in TickerQ.slnx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add src/src.sln to sync-exclude to protect it on net8/net9 branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date/time display for Windows timezone IDs (#717) (#719) Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA format (e.g. "America/New_York") before sending to the frontend, so Intl.DateTimeFormat can correctly render dates in the configured scheduler timezone. Also add defensive fallback in the frontend formatDate() for invalid timezone IDs, and Windows timezone ID pattern matching in getDateFormatRegion() for correct US/EU date format selection. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Skip TickerQ initialization in design-time tools (#712) (#763) * Skip TickerQ initialization when running inside design-time tools (#712) Build-time tools like dotnet-getdocument (used by Microsoft.Extensions.ApiDescription.Server for OpenAPI generation) invoke Program.Main to build the host, which triggers UseTickerQ → InitializeTickerQ → SeedDefinedCronTickers. This causes database queries in a context where no valid connection string exists, crashing the build. Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool entry assemblies and short-circuits InitializeTickerQ before any DB-touching or background service initialization occurs. Closes #712 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712) Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based approach: move all I/O-bound initialization (function discovery, DB seeding, external provider startup) from inline UseTickerQ into a dedicated TickerQInitializerHostedService that runs during host.StartAsync(). Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but never start it, so the hosted service naturally never runs — no heuristics needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix TickerFunctionProvider Build() race condition and add startup validation (#764) - Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests) don't overwrite a populated FrozenDictionary with an empty one (fixes #705) - Initialize static FrozenDictionary fields to .Empty instead of null to prevent NullReferenceException when UseTickerQ() is not called - Add IsBuilt flag to distinguish "UseTickerQ() not called" from "no [TickerFunction] methods found" - Add TickerQStartupValidator IHostedService that warns at startup when UseTickerQ() is missing or no ticker functions are registered - Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 10.2.3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build pipeline: restore only build targets, not samples The sample project uses PackageReference with $(Version) which resolves to the version being built. Restoring the full solution fails because the package isn't published yet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch Sample.WorkerService from PackageReference to ProjectReference Fixes sync build failures on net8/net9 branches where $(Version) resolved to a version that doesn't exist on NuGet yet. All samples now consistently use ProjectReference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add UseAuthorization() to dashboard branch pipeline for Host auth (#408) (#773) When WithHostAuthentication() is configured, dashboard endpoints use RequireAuthorization() metadata. ASP.NET Core's EndpointMiddleware throws InvalidOperationException if no AuthorizationMiddleware exists between UseRouting() and UseEndpoints(). The host app's UseAuthorization() does not propagate into Map() branches, so the dashboard branch needs its own. Closes #408 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Bump version to 10.2.4 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply version-specific overrides for net9 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 22, 2026
* Fixed the issue with dead node release * Fixed the scheduler to handle inline tasks and to not create deadlock on threads of TickerQ * fixed the window time of picking tasks * Fixed the task cancellation issue * fixed the scheduler to show real time threads active * Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723) Clear host-level endpoint routing state in MapPathBaseAware before entering the dashboard branch pipeline. When host-level Map*() calls (e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing, the EndpointRoutingMiddleware may set an endpoint on the HttpContext. The branch's own UseRouting() then skips evaluation (it short-circuits when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket requests to hit the wrong endpoint and return 405. The fix calls SetEndpoint(null) and clears RouteValues when the dashboard base path matches, ensuring the branch's routing middleware re-evaluates against dashboard endpoints. Closes #456 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721) Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the IsEnabled property in CronTickerConfigurations. The former emits DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904). HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server, PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core still sends explicit false values instead of deferring to the DB default. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Switch build and sync workflows to trigger on release - build.yml: trigger on release publish instead of push to main/net8/net9 - sync-version-branches.yml: trigger on release publish instead of push to main - Both keep workflow_dispatch as manual fallback - Updated Discord notification for release context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add test step to release build workflow Tests run before packaging — if tests fail, no NuGet packages are published. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Source Link and symbol package support (#743) * Add Source Link and symbol package support - Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping - Generate .snupkg symbol packages alongside .nupkg - Enable deterministic builds and CI build flag - Embed untracked sources for complete debugging experience Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder - Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename) - Remove src/src.sln (replaced by TickerQ.slnx on main) - Move hub projects to dedicated /hub/ folder in TickerQ.slnx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add src/src.sln to sync-exclude to protect it on net8/net9 branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date/time display for Windows timezone IDs (#717) (#719) Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA format (e.g. "America/New_York") before sending to the frontend, so Intl.DateTimeFormat can correctly render dates in the configured scheduler timezone. Also add defensive fallback in the frontend formatDate() for invalid timezone IDs, and Windows timezone ID pattern matching in getDateFormatRegion() for correct US/EU date format selection. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Skip TickerQ initialization in design-time tools (#712) (#763) * Skip TickerQ initialization when running inside design-time tools (#712) Build-time tools like dotnet-getdocument (used by Microsoft.Extensions.ApiDescription.Server for OpenAPI generation) invoke Program.Main to build the host, which triggers UseTickerQ → InitializeTickerQ → SeedDefinedCronTickers. This causes database queries in a context where no valid connection string exists, crashing the build. Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool entry assemblies and short-circuits InitializeTickerQ before any DB-touching or background service initialization occurs. Closes #712 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712) Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based approach: move all I/O-bound initialization (function discovery, DB seeding, external provider startup) from inline UseTickerQ into a dedicated TickerQInitializerHostedService that runs during host.StartAsync(). Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but never start it, so the hosted service naturally never runs — no heuristics needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix TickerFunctionProvider Build() race condition and add startup validation (#764) - Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests) don't overwrite a populated FrozenDictionary with an empty one (fixes #705) - Initialize static FrozenDictionary fields to .Empty instead of null to prevent NullReferenceException when UseTickerQ() is not called - Add IsBuilt flag to distinguish "UseTickerQ() not called" from "no [TickerFunction] methods found" - Add TickerQStartupValidator IHostedService that warns at startup when UseTickerQ() is missing or no ticker functions are registered - Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 10.2.3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build pipeline: restore only build targets, not samples The sample project uses PackageReference with $(Version) which resolves to the version being built. Restoring the full solution fails because the package isn't published yet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch Sample.WorkerService from PackageReference to ProjectReference Fixes sync build failures on net8/net9 branches where $(Version) resolved to a version that doesn't exist on NuGet yet. All samples now consistently use ProjectReference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add UseAuthorization() to dashboard branch pipeline for Host auth (#408) (#773) When WithHostAuthentication() is configured, dashboard endpoints use RequireAuthorization() metadata. ASP.NET Core's EndpointMiddleware throws InvalidOperationException if no AuthorizationMiddleware exists between UseRouting() and UseEndpoints(). The host app's UseAuthorization() does not propagate into Map() branches, so the dashboard branch needs its own. Closes #408 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Bump version to 10.2.4 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add GitHub issue templates for bug reports, features, and questions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix PostgreSQL incompatible boolean default in CronTicker (#779) * Fix PostgreSQL incompatible boolean default in CronTicker (#778) Replace HasDefaultValueSql("1") with HasDefaultValue(true) so EF Core translates the CLR boolean into the correct SQL literal for each provider (1 for SQL Server/SQLite, TRUE for PostgreSQL, appropriate value for Oracle). The raw SQL literal "1" is invalid for PostgreSQL boolean columns, causing migration failure with error 42804. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Use CLR-side default for CronTicker.IsEnabled instead of DB default Remove HasDefaultValue(true) and HasSentinel(true) from the EF configuration; the C# property initializer (= true) is sufficient. EF Core always includes the property in INSERT/UPDATE SQL, so no provider-specific SQL default translation is needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Adjust WebAPI sample with dashboard integration. (#777) * Update version from 10.2.4 to 10.2.5 * Apply version-specific overrides for net8 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Rafael Câmara <52082556+RafaelJCamara@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Mar 22, 2026
* Updated for the net10 support * update to release version * added release for net9 * added pattern to skip commits using comments on commit for cherry pick merge between branches * remove unecessary build command * fixed the sync * updated cherry detections * try merge based on commit * Fixed the json options to be isolated (#375) * Fix/schedulerbackground (#376) * Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds. * small refactor * fixed the mixd up delete ticker * beta version 17 release (#382) * Feature/improvements (#386) * Made improvements and new feature: request by default not using GZIP compression * Added timezone dashboard support and other fix on features. * Fixed the seefing data * Update README.md * Update README.md * updated beta version * Feature/new improvements (#397) * Added some new features on dashboard and on demand running directly without giving pressure of background scheduler * Added dispatch interfaces * added pagination on machine names * Added test coverage * added examples * Added sample sqlite for samples * Added csproj fules for Sample data * fixed the locking of immediate run ticker in safe for runcondition * fiexed indexing, the scheduler on high run and memory persistence * fixed dashboard path merge * small fixes on manager * Added migration changes for examples * releas of stable version * Update README.md * Release of stable version. * Fix schema assignment logic and add SetSchema method (#415) * Fix schema assignment logic in UseTickerQDbContext and add SetSchema method * Refactor UseTickerQDbContext to simplify schema assignment logic * Add support for enabling/disabling background services (#413) * Checkpoint from VS Code for coding agent session * Remove documentation on separating job queueing from job processing * Update Directory.Build.props * Added logo locally * Fix retry logic and add unit tests for ExecuteTaskAsync (#429) * Add retry logic improvements and unit tests for ExecuteTaskAsync * Refactor retry test setup to use SetupRetryTestFixture for consistency * fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433) * Update Directory.Build.props * Update Directory.Build.props * fix update ExecutionTime for CronTickerOccurrence (#461) * feat: add configurable policy name for Host auth (#482) * Initial plan * Add configurable authorization policy name for Host mode Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * Refactor: Make policy an optional parameter to WithHostAuthentication Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> * fix: Host auth. should not depend on Authorization header (#481) Fixes #446 * [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480) * Removes ASP.NET Core dependency Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services. Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core. Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion. * Resolves NuGet version mismatches Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files. This maintains consistency of dependency versions across all projects. --------- Co-authored-by: EarlJester <shon3322@gmail.com> * Fix missing await to AuthenticateHostAsync call (#494) * Fix #497 (#503) * Fix stackoverflow in JsonExampleGenerator (#519) * Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator. * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs good catch Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Feature/tickerq hub (#508) * Added persistence for the redis. * TickerQHub integration * added ready-to-deploy the new version * pre-release * fix references * Add missing ASP.NET Core package references to TickerQ.SDK (#537) Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/fix aspnetcore namespace xuvot (#540) * Add missing ASP.NET Core package references to TickerQ.SDK Added package references for ASP.NET Core extension packages to resolve CS0234 build errors when deploying. The SDK uses ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing the required package references. Added packages: - Microsoft.AspNetCore.Http.Abstractions - Microsoft.AspNetCore.Http.Results - Microsoft.AspNetCore.Routing - Microsoft.AspNetCore.Mvc.Abstractions https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix ASP.NET Core namespace errors by using Web SDK Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library instead of adding individual ASP.NET Core packages. The individual packages (Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+ and are only available through the shared framework. Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still producing a class library output. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Remove invalid ASP.NET Core package references (#541) The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#542) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Claude/remove invalid aspnetcore packages xuvot (#543) * Remove invalid ASP.NET Core package references The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.) don't exist as standalone NuGet packages for .NET 5+. They were discontinued after .NET Core 2.x and are only available through the shared framework. Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are automatically available through the implicit framework reference. The explicit package references were causing NU1102 errors during restore. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are required for the dashboard middleware and endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.) that are required for the remote execution endpoints. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 * Fix IApplicationBuilder cast in Dashboard ServiceExtensions The UseDashboardApplication callback receives an object (since TickerQ.Utilities doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to IApplicationBuilder before calling extension methods on it. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 --------- Co-authored-by: Claude <noreply@anthropic.com> * Enable NuGet package generation for Web SDK projects (#546) Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard to ensure NuGet packages are generated during build. https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7 Co-authored-by: Claude <noreply@anthropic.com> * Fix #511 and #517: null reference and orphaned cron ticker bugs (#549) - #511: Add null check for CachedDelegate in RunContextFunctionAsync with a clear InvalidOperationException message instead of cryptic NRE - #517: Fix orphaned cron tickers not being cleaned up on restart when their expression was edited via the dashboard. The dashboard update wipes InitIdentifier, causing the seeded-only cleanup to miss them. Now checks all cron tickers against TickerFunctionProvider.TickerFunctions to remove any whose function no longer exists in code. Applied to EF Core, In-Memory, and Redis persistence providers. https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy Co-authored-by: Claude <noreply@anthropic.com> * Fix thread-safety bugs, resource leaks, and scheduling issues (#550) * Fix thread-safety bugs, resource leaks, and scheduling issues across core components Addresses multiple concurrency bugs, resource disposal issues, and adds performance optimizations across the scheduler, cancellation, caching, and persistence layers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * added extension method for WebApplication * pre-release * fix and pre-release * removed the not-needed reference from the Tickerq. * fixed based on the tickerq architecture. * update version * fix and pre-release... * release a stable version * release a stable version along with the new libs for the hub. * Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574) On .NET 9+, the compiler resolves array.Contains() to MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot translate ReadOnlySpan<T> in LINQ expressions, causing InvalidOperationException at runtime for all persistence queries that filter by arrays of IDs. Convert all Guid[] and string[] parameters to List<T> before use in EF Core LINQ .Where() clauses so the compiler resolves to List<T>.Contains() which EF Core can translate to SQL IN clauses. Fixes #460, #462, #465, #466, #470 https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2 Co-authored-by: Claude <noreply@anthropic.com> * fix the dashboard... * Add comprehensive unit tests for core TickerQ components (#582) New test files covering must-have areas that were previously untested: - TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate execution paths, parent-child execution with RunCondition logic, instrumentation logging, null delegate handling - TickerQDispatcherTests: constructor guards, dispatch delegation, empty/null context handling, priority routing - TerminateExecutionExceptionTests: all constructors, status defaults, inner exception preservation - SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression, flush, dispose idempotency, zero-value handling - RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety - WorkItemTests: constructor validation, null guard, token handling - PaginationResultTests: computed properties (TotalPages, HasPreviousPage, HasNextPage, FirstItemIndex, LastItemIndex), edge cases - TickerResultTests: all internal constructors via reflection - TickerHelperTests: serialization with/without GZip, round-trip, custom JSON options, complex objects https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu Co-authored-by: Claude <noreply@anthropic.com> * added rickerq hub to readme file. * Fix authorize against HostAuthorizationPolicy when set (#591) * Add host policy support to AuthService and new unit tests Refactored AuthenticateHostAsync to support host authorization policies using IAuthorizationService. Added comprehensive unit tests for host mode authentication, including policy checks and multiple identity scenarios. * Rename test method for clarity in AuthServiceHostTests Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation. * Update AuthService to pass HttpContext as auth resource Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions. * Added dashboard group name for the openapi (#585) * fixed unit testing and issue of (#586) * added the sample for worker service * fix issue 522 (#587) * Add JSON-serializable tracking fields to TimeTickerEntity (#609) * Add JSON-serializable tracking fields to TimeTickerEntity Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility. * Add custom JSON converter for TimeTickerEntity Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic. * revert that * Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json * Delete src/TickerQ.Dashboard/Properties/launchSettings.json * Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json * Delete src/TickerQ.SDK/Properties/launchSettings.json * Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json * Update .gitignore to remove Aspire project entries Removed ignore rules for sample Aspire projects. * revert * revert * Fix UseApplicationDbContext implementation #498 (#590) * Fix UseApplicationDbContext implementation * Remove unnecessary comment * Move to async implementation * Fix tests * Add sample project for ApplicationDbContext usage * added unit tests for more edge cases coverage. (#623) * Improve branch sync workflow, migrate to slnx, and clean up repo (#628) - Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified - Add .sync-exclude listing version-specific EF Core files and TickerQ.sln - Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+) - Remove tracked SQLite db files (tickerq-console.db*) - Update .gitignore: add *.db, tmpgen/, *.DotSettings.user Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631) Use List<string> instead of HashSet<string> for the allRegisteredFunctions collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL, Oracle MySQL Connector) don't assign type mappings to HashSet parameters in IN expressions, causing InvalidOperationException on EF Core 10. Fixes #621, #624 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add IsEnabled property to CronTickerEntity with full-stack support (#632) Add ability to enable/disable cron tickers without deleting them. Disabled tickers are filtered out of the scheduling pipeline while remaining visible in the dashboard. Includes toggle endpoint, dashboard UI with confirmation dialog, and fixes flaky test caused by parallel test execution sharing static TickerCancellationTokenManager state. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerModelCustomizer not applying configured schema (#635) TickerModelCustomizer was calling configurations without passing the schema, causing migrations to always use the default "ticker" schema instead of the one set via SetSchema(). Now resolves the schema from TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Replace reflection-based JSON serialization in Dashboard with source … (#638) * Replace reflection-based JSON serialization in Dashboard with source generation Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard types, replacing anonymous objects in endpoints with named DTOs. Wires up TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver fallback for user-defined entity types. Fixes StringToByteArrayConverter to use JsonDocument.Parse instead of reflection-based Deserialize<object>. Supports projects using JsonSerializerIsReflectionEnabledByDefault=false. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter - Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding - Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization - Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions - Add TickerQ.Sample.Dashboard.ReflectionFree sample project Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641) UseTickerQ() passes IHost to DashboardApplicationAction, but in the old Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement IApplicationBuilder (only WebApplication does in the new pattern). Fix: Register an IStartupFilter that injects Dashboard middleware into the pipeline when the web host builds it. This works in both patterns: - New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder), and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating. - Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder), and IStartupFilter applies the middleware when the pipeline is built. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#645) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Relax abstractions version constraints and fix sync workflow version handling (#647) - Add DotNetAbstractionsVersion property with open range [8.0.0,) to allow consumers to use newer Microsoft.Extensions.*Abstractions packages - Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions - Fix sync workflow to handle any major version dynamically instead of hardcoded patterns (e.g. 10.x → 8.x now works correctly) - Preserve DotNetAbstractionsVersion from target branch during sync Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648) Move all inline JavaScript to external files served via middleware, allowing the Dashboard to work with strict Content-Security-Policy headers that block 'unsafe-inline'. - Extract Vite's preload script from embedded index.html at startup and serve it as __tickerq-preload.js (cached, before auth) - Serve runtime config (window.TickerQConfig, window.__dynamic_base__) as __tickerq-config.js endpoint (dynamic, before auth) - Replace inline <script> injection with external <script src="..."> references in the HTML template - Remove SanitizeForInlineScript (no longer needed for external files) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Dashboard BasePath not working with UsePathBase (#332) (#651) Replace app.Map() with PathBase-aware routing middleware that strips the PathBase prefix from basePath at request time, so the dashboard works regardless of middleware ordering or whether the user includes the PathBase prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase already ends with basePath (inside a Map branch) to prevent doubled paths in frontend URLs. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652) Make OnModelCreating and TickerModelCustomizer null-safe by falling back to Constants.DefaultSchema when the option builder service is not resolvable (design-time migrations, integration tests, Aspire). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657) Use RootNamespace build property when available, falling back to sanitized assembly name (replacing dashes and other invalid characters with underscores). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix empty request deserialization throwing JsonException (#463) (#658) Add null/empty guard in ReadTickerRequest<T> to return default instead of throwing when no request data is provided. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use browser locale (#581) (#663) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use locale-independent YYYY-MM-DD (#666) * Fix dashboard date format to use browser locale (#581) Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using the browser's locale, so dates display in the user's preferred format. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581) Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add per-function concurrency control via maxConcurrency parameter (#670) * Add per-function concurrency control via maxConcurrency attribute parameter (#458) Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many instances of a specific function can execute concurrently. When set to 0 (default), concurrency is unlimited (preserving backward compatibility). The limit is enforced via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of skipping it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add tests for per-function concurrency gate and dispatcher concurrency behavior Tests cover: - ConcurrencyGate: null for unlimited, semaphore creation, caching, independence - Dispatcher: semaphore acquire/release, release on exception, independent semaphores per function, serialized execution with maxConcurrency=1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply concurrency gate to all QueueAsync call sites Previously only TickerQDispatcher and FallbackBackgroundService used the concurrency gate. This adds it to TickerQSchedulerBackgroundService (the main scheduler loop) and SdkExecutionEndpoint (SDK remote execution). Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK project can resolve it from DI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add scheduler concurrency gate integration tests Verify that TickerQSchedulerBackgroundService correctly uses the concurrency gate when queuing tasks: semaphore acquire/release on success, release on exception, and no semaphore for unlimited functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Centralize test project versions for cross-branch compatibility (#673) * Centralize test project versions via Directory.Build.props Replace hardcoded TargetFramework and package versions in test projects with MSBuild variables (DotNetVersion), matching the pattern used by src projects. This ensures version compatibility when backporting to v8/v9. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add EntityFrameworkCore test project to PR workflow The pr.yaml workflow only built and ran TickerQ.Tests. Added TickerQ.EntityFrameworkCore.Tests to both the build and test steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix design-time DbContext tests failing due to EF Core GetService throw EF Core's GetService<T>() extension throws InvalidOperationException when the service is unresolvable, so the null-conditional (?.) from #652 never executes. Use try-catch to fall back to DefaultSchema. Also add EnableServiceProviderCaching(false) to prevent model cache pollution across tests with the same DbContext type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix AddStackExchangeRedis overriding EF Core persistence provider (#676) * Fix AddStackExchangeRedis overriding EF Core persistence provider (#669) Change Redis persistence registration to TryAddSingleton so EF Core's AddSingleton takes precedence regardless of registration order. Move in-memory provider registration after external providers as a TryAddSingleton fallback. Add dedicated Redis test project with registration precedence tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add functional tests for persistence provider CRUD via managers and DI Exercise ITimeTickerManager, ICronTickerManager, and ITickerPersistenceProvider end-to-end through in-memory, EF Core, and EF Core + Redis configurations. Add InternalsVisibleTo for the new test project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add concurrency and locking tests for persistence providers Test lock acquisition, optimistic concurrency, dead node recovery, concurrent multi-node access, cron occurrence locking, and per-function concurrency gate (serialized/parallel execution, exception safety). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Use atomic Lua scripts for Redis acquire/release/recovery operations Replace all non-atomic read-check-write patterns with Redis Lua scripts that execute atomically (single-threaded), eliminating TOCTOU race conditions in multi-node deployments. This brings Redis provider parity with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees. Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock), ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript (dead node holder match + reset to Idle). 10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers, AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers, ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences, QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync, ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680) - Changed Redis registration test to check service descriptor instead of resolving the provider, which triggered a real Redis connection and failed in CI environments without Redis. - Removed redundant Microsoft.Extensions.Hosting.Abstractions package reference from TickerQ.csproj — it's already a transitive dependency from TickerQ.Utilities, and the explicit lower-bound reference caused NU1605 package downgrade errors. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683) - Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd) - Applied timezone-aware formatting to all date displays including tables, graphs, and date picker - Fixed cron ticker enable/disable dialog showing inverted text - Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * new release 10.2.0 * Simplify EF Core DbContext session pattern (#688) * Simplify EF Core DbContext session pattern and remove dead validation - Remove dead originalDescriptor lookup and throw in UseApplicationDbContext (the variable was unused after PR #590 switched to IDbContextOptionsConfiguration) - Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a simpler DbContextLease struct that handles both IDbContextFactory and scoped DbContext resolution - Remove ITickerDbContextFactory DI registration — BasePersistenceProvider now takes IServiceProvider directly and creates leases via helper methods - Addresses feedback from @jods4 on PR #590 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add unit tests for DbContextLease resolution across DI configurations (#691) Tests cover factory path, scoped path, pooled factory, precedence, instance isolation, dispose behavior, change tracking isolation, and error cases when no DbContext is registered. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * release for fix/ef-core-dbcontext-session-cleanup * Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697) Includes 6 comparison benchmarks (cron parsing, job creation, serialization, startup registration, delegate invocation, concurrent throughput) plus 7 internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Register scoped DbContext from factory for direct injection (#700) (#702) * Register scoped DbContext from factory for direct injection (#700) UseTickerQDbContext only registered IDbContextFactory<TContext> but not TContext itself, preventing users from injecting the DbContext directly. Add a scoped registration that creates instances from the factory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * new fix on db context scope create, release: 10.2.1 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709) * Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder - Move TickerQ.RemoteExecutor to hub/remoteExecutor/ - Move TickerQ.SDK (.NET) to hub/sdks/dotnet/ - Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE - Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging - Add .gitignore for Node.js SDK - Update src.sln project references to new paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix TickerQ.slnx project paths for hub restructuring Update RemoteExecutor and SDK paths in root slnx to match the new hub/ folder structure, fixing CI build and test failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build.yml project paths for hub restructuring Update SDK and RemoteExecutor build/pack paths from src/ to hub/ to match the new folder structure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Add CLA workflow, CLA document, and contributing guidelines (#722) - Add CLA.md with copyright/patent license grants for contributors - Add CONTRIBUTING.md with development setup and contribution process - Add GitHub Actions CLA workflow using contributor-assistant/github-action - Allowlist dependabot, github-actions, and renovate bots Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Scope CLA workflow to main branch only Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README.md (#726) * Rewrite README: cleaner structure, feature highlights, contributors section Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Discord badge to use static badge instead of invalid server ID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update README tagline and subtitle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata - Update LICENSE, CLA.md, README.md to reference Arcenox LLC - Add Authors and Copyright tags to Directory.Build.props - Clean trailing whitespace in LICENSE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add SECURITY.md with vulnerability reporting policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rewrite branch sync from cherry-pick to merge-based approach (#744) - Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally) - Add .sync-overrides config for generic version replacement rules - Apply version overrides from config instead of hardcoded sed commands - Post PR comment with sync details (restored files + version overrides applied) - Auto-resolve conflicts: excluded files keep target, everything else takes main Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-overrides loading from target branch instead of main The .sync-overrides file only exists on main, but was being loaded from the target branch (net8/net9) before the merge. Load it from main using git show instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync workflow: load exclude/overrides from main, escape sed regex - Load .sync-exclude from main (not target branch) so it's always up to date - Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix version-range sed regex error by using awk for replacements Values like [8.0.0,9.0.0) contain regex special chars that break sed. Use awk string matching instead which handles literal characters. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI - Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion) - Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion) - Add overrides for tests/Directory.Build.props and sample/benchmark csproj files - Detect .NET version and solution file dynamically in PR and build workflows - Fix PR comment table formatting (property column was empty) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Centralize version props in src/Directory.Build.props - src/Directory.Build.props is the single source of truth for TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion - tests/samples/benchmarks import from src/ and disable packaging - Replace all hardcoded package versions with $(DotNetVersion) - Simplify .sync-overrides to only override src/Directory.Build.props - Detect .NET version dynamically in PR and build workflows Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add CustomizerServiceDescriptor.cs to .sync-exclude Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add retry for PR comment in sync workflow Race condition: PR may not be indexed when comment step runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723) Clear host-level endpoint routing state in MapPathBaseAware before entering the dashboard branch pipeline. When host-level Map*() calls (e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing, the EndpointRoutingMiddleware may set an endpoint on the HttpContext. The branch's own UseRouting() then skips evaluation (it short-circuits when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket requests to hit the wrong endpoint and return 405. The fix calls SetEndpoint(null) and clears RouteValues when the dashboard base path matches, ensuring the branch's routing middleware re-evaluates against dashboard endpoints. Closes #456 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721) Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the IsEnabled property in CronTickerConfigurations. The former emits DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904). HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server, PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core still sends explicit false values instead of deferring to the DB default. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Switch build and sync workflows to trigger on release - build.yml: trigger on release publish instead of push to main/net8/net9 - sync-version-branches.yml: trigger on release publish instead of push to main - Both keep workflow_dispatch as manual fallback - Updated Discord notification for release context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add test step to release build workflow Tests run before packaging — if tests fail, no NuGet packages are published. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add Source Link and symbol package support (#743) * Add Source Link and symbol package support - Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping - Generate .snupkg symbol packages alongside .nupkg - Enable deterministic builds and CI build flag - Embed untracked sources for complete debugging experience Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder - Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename) - Remove src/src.sln (replaced by TickerQ.slnx on main) - Move hub projects to dedicated /hub/ folder in TickerQ.slnx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add src/src.sln to sync-exclude to protect it on net8/net9 branches Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix dashboard date/time display for Windows timezone IDs (#717) (#719) Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA format (e.g. "America/New_York") before sending to the frontend, so Intl.DateTimeFormat can correctly render dates in the configured scheduler timezone. Also add defensive fallback in the frontend formatDate() for invalid timezone IDs, and Windows timezone ID pattern matching in getDateFormatRegion() for correct US/EU date format selection. Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Skip TickerQ initialization in design-time tools (#712) (#763) * Skip TickerQ initialization when running inside design-time tools (#712) Build-time tools like dotnet-getdocument (used by Microsoft.Extensions.ApiDescription.Server for OpenAPI generation) invoke Program.Main to build the host, which triggers UseTickerQ → InitializeTickerQ → SeedDefinedCronTickers. This causes database queries in a context where no valid connection string exists, crashing the build. Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool entry assemblies and short-circuits InitializeTickerQ before any DB-touching or background service initialization occurs. Closes #712 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712) Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based approach: move all I/O-bound initialization (function discovery, DB seeding, external provider startup) from inline UseTickerQ into a dedicated TickerQInitializerHostedService that runs during host.StartAsync(). Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but never start it, so the hosted service naturally never runs — no heuristics needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix TickerFunctionProvider Build() race condition and add startup validation (#764) - Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests) don't overwrite a populated FrozenDictionary with an empty one (fixes #705) - Initialize static FrozenDictionary fields to .Empty instead of null to prevent NullReferenceException when UseTickerQ() is not called - Add IsBuilt flag to distinguish "UseTickerQ() not called" from "no [TickerFunction] methods found" - Add TickerQStartupValidator IHostedService that warns at startup when UseTickerQ() is missing or no ticker functions are registered - Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 10.2.3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix build pipeline: restore only build targets, not samples The sample project uses PackageReference with $(Version) which resolves to the version being built. Restoring the full solution fails because the package isn't published yet. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Switch Sample.WorkerService from PackageReference to ProjectReference Fixes sync build failures on net8/net9 branches where $(Version) resolved to a version that doesn't exist on NuGet yet. All samples now consistently use ProjectReference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add UseAuthorization() to dashboard branch pipeline for Host auth (#408) (#773) When WithHostAuthentication() is configured, dashboard endpoints use RequireAuthorization() metadata. ASP.NET Core's EndpointMiddleware throws InvalidOperationException if no AuthorizationMiddleware exists between UseRouting() and UseEndpoints(). The host app's UseAuthorization() does not propagate into Map() branches, so the dashboard branch needs its own. Closes #408 Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Bump version to 10.2.4 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add GitHub issue templates for bug reports, features, and questions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix PostgreSQL incompatible boolean default in CronTicker (#779) * Fix PostgreSQL incompatible boolean default in CronTicker (#778) Replace HasDefaultValueSql("1") with HasDefaultValue(true) so EF Core translates the CLR boolean into the correct SQL literal for each provider (1 for SQL Server/SQLite, TRUE for PostgreSQL, appropriate value for Oracle). The raw SQL literal "1" is invalid for PostgreSQL boolean columns, causing migration failure with error 42804. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Use CLR-side default for CronTicker.IsEnabled instead of DB default Remove HasDefaultValue(true) and HasSentinel(true) from the EF configuration; the C# property initializer (= true) is sufficient. EF Core always includes the property in INSERT/UPDATE SQL, so no provider-specific SQL default translation is needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Adjust WebAPI sample with dashboard integration. (#777) * Update version from 10.2.4 to 10.2.5 * Apply version-specific overrides for net9 --------- Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com> Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com> Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com> Co-authored-by: jods <jods4@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com> Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com> Co-authored-by: EarlJester <shon3322@gmail.com> Co-authored-by: stevewoj <steve.wojciechowski@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl> Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com> Co-authored-by: albert-miden <albert@miden.co> Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local> Co-authored-by: Rafael Câmara <52082556+RafaelJCamara@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Apr 13, 2026
* Updated for the net10 support
* update to release version
* added release for net9
* added pattern to skip commits using comments on commit for cherry pick merge between branches
* remove unecessary build command
* fixed the sync
* updated cherry detections
* try merge based on commit
* Fixed the json options to be isolated (#375)
* Fix/schedulerbackground (#376)
* Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds.
* small refactor
* fixed the mixd up delete ticker
* beta version 17 release (#382)
* Feature/improvements (#386)
* Made improvements and new feature: request by default not using GZIP compression
* Added timezone dashboard support and other fix on features.
* Fixed the seefing data
* Update README.md
* Update README.md
* updated beta version
* Feature/new improvements (#397)
* Added some new features on dashboard and on demand running directly without giving pressure of background scheduler
* Added dispatch interfaces
* added pagination on machine names
* Added test coverage
* added examples
* Added sample sqlite for samples
* Added csproj fules for Sample data
* fixed the locking of immediate run ticker in safe for runcondition
* fiexed indexing, the scheduler on high run and memory persistence
* fixed dashboard path merge
* small fixes on manager
* Added migration changes for examples
* releas of stable version
* Update README.md
* Release of stable version.
* Fix schema assignment logic and add SetSchema method (#415)
* Fix schema assignment logic in UseTickerQDbContext and add SetSchema method
* Refactor UseTickerQDbContext to simplify schema assignment logic
* Add support for enabling/disabling background services (#413)
* Checkpoint from VS Code for coding agent session
* Remove documentation on separating job queueing from job processing
* Update Directory.Build.props
* Added logo locally
* Fix retry logic and add unit tests for ExecuteTaskAsync (#429)
* Add retry logic improvements and unit tests for ExecuteTaskAsync
* Refactor retry test setup to use SetupRetryTestFixture for consistency
* fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433)
* Update Directory.Build.props
* Update Directory.Build.props
* fix update ExecutionTime for CronTickerOccurrence (#461)
* feat: add configurable policy name for Host auth (#482)
* Initial plan
* Add configurable authorization policy name for Host mode
Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com>
* Refactor: Make policy an optional parameter to WithHostAuthentication
Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com>
* fix: Host auth. should not depend on Authorization header (#481)
Fixes #446
* [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480)
* Removes ASP.NET Core dependency
Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services.
Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core.
Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion.
* Resolves NuGet version mismatches
Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files.
This maintains consistency of dependency versions across all projects.
---------
Co-authored-by: EarlJester <shon3322@gmail.com>
* Fix missing await to AuthenticateHostAsync call (#494)
* Fix #497 (#503)
* Fix stackoverflow in JsonExampleGenerator (#519)
* Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator.
* Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs
good catch
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Feature/tickerq hub (#508)
* Added persistence for the redis.
* TickerQHub integration
* added ready-to-deploy the new version
* pre-release
* fix references
* Add missing ASP.NET Core package references to TickerQ.SDK (#537)
Added package references for ASP.NET Core extension packages to resolve
CS0234 build errors when deploying. The SDK uses ASP.NET Core types
(IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing
the required package references.
Added packages:
- Microsoft.AspNetCore.Http.Abstractions
- Microsoft.AspNetCore.Http.Results
- Microsoft.AspNetCore.Routing
- Microsoft.AspNetCore.Mvc.Abstractions
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
Co-authored-by: Claude <noreply@anthropic.com>
* Claude/fix aspnetcore namespace xuvot (#540)
* Add missing ASP.NET Core package references to TickerQ.SDK
Added package references for ASP.NET Core extension packages to resolve
CS0234 build errors when deploying. The SDK uses ASP.NET Core types
(IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing
the required package references.
Added packages:
- Microsoft.AspNetCore.Http.Abstractions
- Microsoft.AspNetCore.Http.Results
- Microsoft.AspNetCore.Routing
- Microsoft.AspNetCore.Mvc.Abstractions
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix ASP.NET Core namespace errors by using Web SDK
Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library
instead of adding individual ASP.NET Core packages. The individual packages
(Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+
and are only available through the shared framework.
Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types
(IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still
producing a class library output.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Remove invalid ASP.NET Core package references (#541)
The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.)
don't exist as standalone NuGet packages for .NET 5+. They were discontinued
after .NET Core 2.x and are only available through the shared framework.
Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are
automatically available through the implicit framework reference. The
explicit package references were causing NU1102 errors during restore.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
Co-authored-by: Claude <noreply@anthropic.com>
* Claude/remove invalid aspnetcore packages xuvot (#542)
* Remove invalid ASP.NET Core package references
The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.)
don't exist as standalone NuGet packages for .NET 5+. They were discontinued
after .NET Core 2.x and are only available through the shared framework.
Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are
automatically available through the implicit framework reference. The
explicit package references were causing NU1102 errors during restore.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types
Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library
to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are
required for the dashboard middleware and endpoints.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types
Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library
to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.)
that are required for the remote execution endpoints.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Claude/remove invalid aspnetcore packages xuvot (#543)
* Remove invalid ASP.NET Core package references
The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.)
don't exist as standalone NuGet packages for .NET 5+. They were discontinued
after .NET Core 2.x and are only available through the shared framework.
Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are
automatically available through the implicit framework reference. The
explicit package references were causing NU1102 errors during restore.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types
Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library
to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are
required for the dashboard middleware and endpoints.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types
Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library
to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.)
that are required for the remote execution endpoints.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix IApplicationBuilder cast in Dashboard ServiceExtensions
The UseDashboardApplication callback receives an object (since TickerQ.Utilities
doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to
IApplicationBuilder before calling extension methods on it.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Enable NuGet package generation for Web SDK projects (#546)
Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit
IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard
to ensure NuGet packages are generated during build.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
Co-authored-by: Claude <noreply@anthropic.com>
* Fix #511 and #517: null reference and orphaned cron ticker bugs (#549)
- #511: Add null check for CachedDelegate in RunContextFunctionAsync with
a clear InvalidOperationException message instead of cryptic NRE
- #517: Fix orphaned cron tickers not being cleaned up on restart when
their expression was edited via the dashboard. The dashboard update
wipes InitIdentifier, causing the seeded-only cleanup to miss them.
Now checks all cron tickers against TickerFunctionProvider.TickerFunctions
to remove any whose function no longer exists in code. Applied to
EF Core, In-Memory, and Redis persistence providers.
https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy
Co-authored-by: Claude <noreply@anthropic.com>
* Fix thread-safety bugs, resource leaks, and scheduling issues (#550)
* Fix thread-safety bugs, resource leaks, and scheduling issues across core components
Addresses multiple concurrency bugs, resource disposal issues, and adds
performance optimizations across the scheduler, cancellation, caching,
and persistence layers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* added extension method for WebApplication
* pre-release
* fix and pre-release
* removed the not-needed reference from the Tickerq.
* fixed based on the tickerq architecture.
* update version
* fix and pre-release...
* release a stable version
* release a stable version along with the new libs for the hub.
* Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574)
On .NET 9+, the compiler resolves array.Contains() to
MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot
translate ReadOnlySpan<T> in LINQ expressions, causing
InvalidOperationException at runtime for all persistence queries that
filter by arrays of IDs.
Convert all Guid[] and string[] parameters to List<T> before use in
EF Core LINQ .Where() clauses so the compiler resolves to
List<T>.Contains() which EF Core can translate to SQL IN clauses.
Fixes #460, #462, #465, #466, #470
https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2
Co-authored-by: Claude <noreply@anthropic.com>
* fix the dashboard...
* Add comprehensive unit tests for core TickerQ components (#582)
New test files covering must-have areas that were previously untested:
- TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate
execution paths, parent-child execution with RunCondition logic,
instrumentation logging, null delegate handling
- TickerQDispatcherTests: constructor guards, dispatch delegation,
empty/null context handling, priority routing
- TerminateExecutionExceptionTests: all constructors, status defaults,
inner exception preservation
- SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression,
flush, dispose idempotency, zero-value handling
- RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety
- WorkItemTests: constructor validation, null guard, token handling
- PaginationResultTests: computed properties (TotalPages, HasPreviousPage,
HasNextPage, FirstItemIndex, LastItemIndex), edge cases
- TickerResultTests: all internal constructors via reflection
- TickerHelperTests: serialization with/without GZip, round-trip,
custom JSON options, complex objects
https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu
Co-authored-by: Claude <noreply@anthropic.com>
* added rickerq hub to readme file.
* Fix authorize against HostAuthorizationPolicy when set (#591)
* Add host policy support to AuthService and new unit tests
Refactored AuthenticateHostAsync to support host authorization
policies using IAuthorizationService. Added comprehensive
unit tests for host mode authentication, including policy
checks and multiple identity scenarios.
* Rename test method for clarity in AuthServiceHostTests
Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation.
* Update AuthService to pass HttpContext as auth resource
Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions.
* Added dashboard group name for the openapi (#585)
* fixed unit testing and issue of (#586)
* added the sample for worker service
* fix issue 522 (#587)
* Add JSON-serializable tracking fields to TimeTickerEntity (#609)
* Add JSON-serializable tracking fields to TimeTickerEntity
Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility.
* Add custom JSON converter for TimeTickerEntity
Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic.
* revert that
* Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json
* Delete src/TickerQ.Dashboard/Properties/launchSettings.json
* Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json
* Delete src/TickerQ.SDK/Properties/launchSettings.json
* Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json
* Update .gitignore to remove Aspire project entries
Removed ignore rules for sample Aspire projects.
* revert
* revert
* Fix UseApplicationDbContext implementation #498 (#590)
* Fix UseApplicationDbContext implementation
* Remove unnecessary comment
* Move to async implementation
* Fix tests
* Add sample project for ApplicationDbContext usage
* added unit tests for more edge cases coverage. (#623)
* Improve branch sync workflow, migrate to slnx, and clean up repo (#628)
- Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified
- Add .sync-exclude listing version-specific EF Core files and TickerQ.sln
- Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+)
- Remove tracked SQLite db files (tickerq-console.db*)
- Update .gitignore: add *.db, tmpgen/, *.DotSettings.user
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631)
Use List<string> instead of HashSet<string> for the allRegisteredFunctions
collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL,
Oracle MySQL Connector) don't assign type mappings to HashSet parameters in
IN expressions, causing InvalidOperationException on EF Core 10.
Fixes #621, #624
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add IsEnabled property to CronTickerEntity with full-stack support (#632)
Add ability to enable/disable cron tickers without deleting them.
Disabled tickers are filtered out of the scheduling pipeline while
remaining visible in the dashboard. Includes toggle endpoint, dashboard
UI with confirmation dialog, and fixes flaky test caused by parallel
test execution sharing static TickerCancellationTokenManager state.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix TickerModelCustomizer not applying configured schema (#635)
TickerModelCustomizer was calling configurations without passing the
schema, causing migrations to always use the default "ticker" schema
instead of the one set via SetSchema(). Now resolves the schema from
TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Replace reflection-based JSON serialization in Dashboard with source … (#638)
* Replace reflection-based JSON serialization in Dashboard with source generation
Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard
types, replacing anonymous objects in endpoints with named DTOs. Wires up
TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver
fallback for user-defined entity types. Fixes StringToByteArrayConverter to
use JsonDocument.Parse instead of reflection-based Deserialize<object>.
Supports projects using JsonSerializerIsReflectionEnabledByDefault=false.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter
- Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding
- Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization
- Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions
- Add TickerQ.Sample.Dashboard.ReflectionFree sample project
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641)
UseTickerQ() passes IHost to DashboardApplicationAction, but in the old
Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement
IApplicationBuilder (only WebApplication does in the new pattern).
Fix: Register an IStartupFilter that injects Dashboard middleware into the
pipeline when the web host builds it. This works in both patterns:
- New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder),
and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating.
- Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder),
and IStartupFilter applies the middleware when the pipeline is built.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Relax abstractions version constraints and fix sync workflow version handling (#645)
- Add DotNetAbstractionsVersion property with open range [8.0.0,) to
allow consumers to use newer Microsoft.Extensions.*Abstractions packages
- Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions
- Fix sync workflow to handle any major version dynamically instead of
hardcoded patterns (e.g. 10.x → 8.x now works correctly)
- Preserve DotNetAbstractionsVersion from target branch during sync
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Relax abstractions version constraints and fix sync workflow version handling (#647)
- Add DotNetAbstractionsVersion property with open range [8.0.0,) to
allow consumers to use newer Microsoft.Extensions.*Abstractions packages
- Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions
- Fix sync workflow to handle any major version dynamically instead of
hardcoded patterns (e.g. 10.x → 8.x now works correctly)
- Preserve DotNetAbstractionsVersion from target branch during sync
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648)
Move all inline JavaScript to external files served via middleware,
allowing the Dashboard to work with strict Content-Security-Policy
headers that block 'unsafe-inline'.
- Extract Vite's preload script from embedded index.html at startup
and serve it as __tickerq-preload.js (cached, before auth)
- Serve runtime config (window.TickerQConfig, window.__dynamic_base__)
as __tickerq-config.js endpoint (dynamic, before auth)
- Replace inline <script> injection with external <script src="...">
references in the HTML template
- Remove SanitizeForInlineScript (no longer needed for external files)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Dashboard BasePath not working with UsePathBase (#332) (#651)
Replace app.Map() with PathBase-aware routing middleware that strips the
PathBase prefix from basePath at request time, so the dashboard works
regardless of middleware ordering or whether the user includes the PathBase
prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase
already ends with basePath (inside a Map branch) to prevent doubled paths
in frontend URLs.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652)
Make OnModelCreating and TickerModelCustomizer null-safe by falling back
to Constants.DefaultSchema when the option builder service is not
resolvable (design-time migrations, integration tests, Aspire).
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657)
Use RootNamespace build property when available, falling back to sanitized
assembly name (replacing dashes and other invalid characters with underscores).
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix empty request deserialization throwing JsonException (#463) (#658)
Add null/empty guard in ReadTickerRequest<T> to return default
instead of throwing when no request data is provided.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date format to use browser locale (#581) (#663)
Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using
the browser's locale, so dates display in the user's preferred format.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date format to use locale-independent YYYY-MM-DD (#666)
* Fix dashboard date format to use browser locale (#581)
Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using
the browser's locale, so dates display in the user's preferred format.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581)
Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts
using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless
of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add per-function concurrency control via maxConcurrency parameter (#670)
* Add per-function concurrency control via maxConcurrency attribute parameter (#458)
Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many
instances of a specific function can execute concurrently. When set to 0 (default),
concurrency is unlimited (preserving backward compatibility). The limit is enforced
via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of
skipping it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add tests for per-function concurrency gate and dispatcher concurrency behavior
Tests cover:
- ConcurrencyGate: null for unlimited, semaphore creation, caching, independence
- Dispatcher: semaphore acquire/release, release on exception, independent
semaphores per function, serialized execution with maxConcurrency=1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Apply concurrency gate to all QueueAsync call sites
Previously only TickerQDispatcher and FallbackBackgroundService used the
concurrency gate. This adds it to TickerQSchedulerBackgroundService (the
main scheduler loop) and SdkExecutionEndpoint (SDK remote execution).
Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK
project can resolve it from DI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add scheduler concurrency gate integration tests
Verify that TickerQSchedulerBackgroundService correctly uses the
concurrency gate when queuing tasks: semaphore acquire/release on
success, release on exception, and no semaphore for unlimited functions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Centralize test project versions for cross-branch compatibility (#673)
* Centralize test project versions via Directory.Build.props
Replace hardcoded TargetFramework and package versions in test projects
with MSBuild variables (DotNetVersion), matching the pattern used by src
projects. This ensures version compatibility when backporting to v8/v9.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add EntityFrameworkCore test project to PR workflow
The pr.yaml workflow only built and ran TickerQ.Tests. Added
TickerQ.EntityFrameworkCore.Tests to both the build and test steps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix design-time DbContext tests failing due to EF Core GetService throw
EF Core's GetService<T>() extension throws InvalidOperationException
when the service is unresolvable, so the null-conditional (?.) from
#652 never executes. Use try-catch to fall back to DefaultSchema.
Also add EnableServiceProviderCaching(false) to prevent model cache
pollution across tests with the same DbContext type.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix AddStackExchangeRedis overriding EF Core persistence provider (#676)
* Fix AddStackExchangeRedis overriding EF Core persistence provider (#669)
Change Redis persistence registration to TryAddSingleton so EF Core's
AddSingleton takes precedence regardless of registration order. Move
in-memory provider registration after external providers as a
TryAddSingleton fallback. Add dedicated Redis test project with
registration precedence tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add functional tests for persistence provider CRUD via managers and DI
Exercise ITimeTickerManager, ICronTickerManager, and
ITickerPersistenceProvider end-to-end through in-memory, EF Core,
and EF Core + Redis configurations. Add InternalsVisibleTo for the
new test project.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add concurrency and locking tests for persistence providers
Test lock acquisition, optimistic concurrency, dead node recovery,
concurrent multi-node access, cron occurrence locking, and
per-function concurrency gate (serialized/parallel execution,
exception safety).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use atomic Lua scripts for Redis acquire/release/recovery operations
Replace all non-atomic read-check-write patterns with Redis Lua scripts
that execute atomically (single-threaded), eliminating TOCTOU race
conditions in multi-node deployments. This brings Redis provider parity
with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees.
Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock),
ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript
(dead node holder match + reset to Idle).
10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers,
AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers,
ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences,
QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync,
ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680)
- Changed Redis registration test to check service descriptor instead
of resolving the provider, which triggered a real Redis connection
and failed in CI environments without Redis.
- Removed redundant Microsoft.Extensions.Hosting.Abstractions package
reference from TickerQ.csproj — it's already a transitive dependency
from TickerQ.Utilities, and the explicit lower-bound reference caused
NU1605 package downgrade errors.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683)
- Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd)
- Applied timezone-aware formatting to all date displays including tables, graphs, and date picker
- Fixed cron ticker enable/disable dialog showing inverted text
- Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* new release 10.2.0
* Simplify EF Core DbContext session pattern (#688)
* Simplify EF Core DbContext session pattern and remove dead validation
- Remove dead originalDescriptor lookup and throw in UseApplicationDbContext
(the variable was unused after PR #590 switched to IDbContextOptionsConfiguration)
- Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a
simpler DbContextLease struct that handles both IDbContextFactory and
scoped DbContext resolution
- Remove ITickerDbContextFactory DI registration — BasePersistenceProvider
now takes IServiceProvider directly and creates leases via helper methods
- Addresses feedback from @jods4 on PR #590
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add unit tests for DbContextLease resolution across DI configurations (#691)
Tests cover factory path, scoped path, pooled factory, precedence,
instance isolation, dispose behavior, change tracking isolation,
and error cases when no DbContext is registered.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* release for fix/ef-core-dbcontext-session-cleanup
* Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697)
Includes 6 comparison benchmarks (cron parsing, job creation, serialization,
startup registration, delegate invocation, concurrent throughput) plus 7
internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Register scoped DbContext from factory for direct injection (#700) (#702)
* Register scoped DbContext from factory for direct injection (#700)
UseTickerQDbContext only registered IDbContextFactory<TContext> but not
TContext itself, preventing users from injecting the DbContext directly.
Add a scoped registration that creates instances from the factory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* new fix on db context scope create, release: 10.2.1
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709)
* Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder
- Move TickerQ.RemoteExecutor to hub/remoteExecutor/
- Move TickerQ.SDK (.NET) to hub/sdks/dotnet/
- Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE
- Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging
- Add .gitignore for Node.js SDK
- Update src.sln project references to new paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix TickerQ.slnx project paths for hub restructuring
Update RemoteExecutor and SDK paths in root slnx to match the new
hub/ folder structure, fixing CI build and test failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix build.yml project paths for hub restructuring
Update SDK and RemoteExecutor build/pack paths from src/ to hub/
to match the new folder structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add CLA workflow, CLA document, and contributing guidelines (#722)
- Add CLA.md with copyright/patent license grants for contributors
- Add CONTRIBUTING.md with development setup and contribution process
- Add GitHub Actions CLA workflow using contributor-assistant/github-action
- Allowlist dependabot, github-actions, and renovate bots
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Scope CLA workflow to main branch only
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update README.md (#726)
* Rewrite README: cleaner structure, feature highlights, contributors section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Discord badge to use static badge instead of invalid server ID
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update README tagline and subtitle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata
- Update LICENSE, CLA.md, README.md to reference Arcenox LLC
- Add Authors and Copyright tags to Directory.Build.props
- Clean trailing whitespace in LICENSE
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add SECURITY.md with vulnerability reporting policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Rewrite branch sync from cherry-pick to merge-based approach (#744)
- Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally)
- Add .sync-overrides config for generic version replacement rules
- Apply version overrides from config instead of hardcoded sed commands
- Post PR comment with sync details (restored files + version overrides applied)
- Auto-resolve conflicts: excluded files keep target, everything else takes main
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix sync-overrides loading from target branch instead of main
The .sync-overrides file only exists on main, but was being loaded
from the target branch (net8/net9) before the merge. Load it from
main using git show instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix sync workflow: load exclude/overrides from main, escape sed regex
- Load .sync-exclude from main (not target branch) so it's always up to date
- Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix version-range sed regex error by using awk for replacements
Values like [8.0.0,9.0.0) contain regex special chars that break sed.
Use awk string matching instead which handles literal characters.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI
- Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion)
- Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion)
- Add overrides for tests/Directory.Build.props and sample/benchmark csproj files
- Detect .NET version and solution file dynamically in PR and build workflows
- Fix PR comment table formatting (property column was empty)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Centralize version props in src/Directory.Build.props
- src/Directory.Build.props is the single source of truth for
TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion
- tests/samples/benchmarks import from src/ and disable packaging
- Replace all hardcoded package versions with $(DotNetVersion)
- Simplify .sync-overrides to only override src/Directory.Build.props
- Detect .NET version dynamically in PR and build workflows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add CustomizerServiceDescriptor.cs to .sync-exclude
Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add retry for PR comment in sync workflow
Race condition: PR may not be indexed when comment step runs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723)
Clear host-level endpoint routing state in MapPathBaseAware before
entering the dashboard branch pipeline. When host-level Map*() calls
(e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing,
the EndpointRoutingMiddleware may set an endpoint on the HttpContext.
The branch's own UseRouting() then skips evaluation (it short-circuits
when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket
requests to hit the wrong endpoint and return 405.
The fix calls SetEndpoint(null) and clears RouteValues when the
dashboard base path matches, ensuring the branch's routing middleware
re-evaluates against dashboard endpoints.
Closes #456
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721)
Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the
IsEnabled property in CronTickerConfigurations. The former emits
DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904).
HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server,
PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core
still sends explicit false values instead of deferring to the DB default.
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Switch build and sync workflows to trigger on release
- build.yml: trigger on release publish instead of push to main/net8/net9
- sync-version-branches.yml: trigger on release publish instead of push to main
- Both keep workflow_dispatch as manual fallback
- Updated Discord notification for release context
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add test step to release build workflow
Tests run before packaging — if tests fail, no NuGet packages are published.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Source Link and symbol package support (#743)
* Add Source Link and symbol package support
- Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping
- Generate .snupkg symbol packages alongside .nupkg
- Enable deterministic builds and CI build flag
- Embed untracked sources for complete debugging experience
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder
- Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename)
- Remove src/src.sln (replaced by TickerQ.slnx on main)
- Move hub projects to dedicated /hub/ folder in TickerQ.slnx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add src/src.sln to sync-exclude to protect it on net8/net9 branches
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date/time display for Windows timezone IDs (#717) (#719)
Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA
format (e.g. "America/New_York") before sending to the frontend, so
Intl.DateTimeFormat can correctly render dates in the configured
scheduler timezone. Also add defensive fallback in the frontend
formatDate() for invalid timezone IDs, and Windows timezone ID
pattern matching in getDateFormatRegion() for correct US/EU date
format selection.
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Skip TickerQ initialization in design-time tools (#712) (#763)
* Skip TickerQ initialization when running inside design-time tools (#712)
Build-time tools like dotnet-getdocument (used by
Microsoft.Extensions.ApiDescription.Server for OpenAPI generation)
invoke Program.Main to build the host, which triggers UseTickerQ →
InitializeTickerQ → SeedDefinedCronTickers. This causes database
queries in a context where no valid connection string exists, crashing
the build.
Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool
entry assemblies and short-circuits InitializeTickerQ before any
DB-touching or background service initialization occurs.
Closes #712
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712)
Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based
approach: move all I/O-bound initialization (function discovery, DB seeding,
external provider startup) from inline UseTickerQ into a dedicated
TickerQInitializerHostedService that runs during host.StartAsync().
Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but
never start it, so the hosted service naturally never runs — no heuristics needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix TickerFunctionProvider Build() race condition and add startup validation (#764)
- Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests)
don't overwrite a populated FrozenDictionary with an empty one (fixes #705)
- Initialize static FrozenDictionary fields to .Empty instead of null to
prevent NullReferenceException when UseTickerQ() is not called
- Add IsBuilt flag to distinguish "UseTickerQ() not called" from
"no [TickerFunction] methods found"
- Add TickerQStartupValidator IHostedService that warns at startup when
UseTickerQ() is missing or no ticker functions are registered
- Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Bump version to 10.2.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix build pipeline: restore only build targets, not samples
The sample project uses PackageReference with $(Version) which resolves
to the version being built. Restoring the full solution fails because
the package isn't published yet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Switch Sample.WorkerService from PackageReference to ProjectReference
Fixes sync build failures on net8/net9 branches where $(Version) resolved
to a version that doesn't exist on NuGet yet. All samples now consistently
use ProjectReference.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add UseAuthorization() to dashboard branch pipeline for Host auth (#408) (#773)
When WithHostAuthentication() is configured, dashboard endpoints use
RequireAuthorization() metadata. ASP.NET Core's EndpointMiddleware throws
InvalidOperationException if no AuthorizationMiddleware exists between
UseRouting() and UseEndpoints(). The host app's UseAuthorization() does
not propagate into Map() branches, so the dashboard branch needs its own.
Closes #408
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Bump version to 10.2.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add GitHub issue templates for bug reports, features, and questions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix PostgreSQL incompatible boolean default in CronTicker (#779)
* Fix PostgreSQL incompatible boolean default in CronTicker (#778)
Replace HasDefaultValueSql("1") with HasDefaultValue(true) so EF Core
translates the CLR boolean into the correct SQL literal for each
provider (1 for SQL Server/SQLite, TRUE for PostgreSQL, appropriate
value for Oracle). The raw SQL literal "1" is invalid for PostgreSQL
boolean columns, causing migration failure with error 42804.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Use CLR-side default for CronTicker.IsEnabled instead of DB default
Remove HasDefaultValue(true) and HasSentinel(true) from the EF
configuration; the C# property initializer (= true) is sufficient.
EF Core always includes the property in INSERT/UPDATE SQL, so no
provider-specific SQL default translation is needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Adjust WebAPI sample with dashboard integration. (#777)
* Update version from 10.2.4 to 10.2.5
* feat: Simplify host authentication by removing direct access key input and updating UI/logic for a click-to-authenticate flow. (#786)
* Fix startup cron occurrence duplicate scheduling (#776) (#785)
* Fix startup cron occurrence duplicate scheduling (#776)
At startup, past-due cron occurrences left over from a previous
application lifecycle were being caught up by the fallback service,
causing unexpected duplicate executions. This was most visible when
stopping and restarting the application — the cron job would fire
immediately for the missed slot AND schedule normally for the next
slot.
The fix adds a startup cleanup step that marks stale past-due
occurrences (ExecutionTime more than 5 seconds old, still in
Idle/Queued status) as Skipped before the scheduler and fallback
services begin. This prevents the fallback from catching up
occurrences from a previous lifecycle while preserving normal
fallback behavior for the current lifecycle.
The 5-second grace period ensures that very recent occurrences
(e.g. from a sub-second restart) are not incorrectly skipped.
Closes #776
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Refactor stale cron occurrence cleanup into opt-in configurable option
Make stale-cron-occurrence skipping disabled by default (threshold = Zero)
and expose SkipStaleCronOccurrencesOnStartup() on TickerOptionsBuilder as
the primary opt-in API. The threshold is now passed through the full call
chain instead of being hardcoded in persistence providers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Refactor Redis persistence provider: extract helpers, base class, Lua scripts, AOT support (#793)
- Extract BaseRedisPersistenceProvider with core scheduler logic (mirrors EF Core pattern)
- Extract Helpers: RedisKeyBuilder, RedisIndexManager, RedisSerializer
- Move Lua scripts to embedded .lua files (Acquire, Release, RecoverDeadNode)
- AOT: use KEYS[]/ARGV[] notation, source-gen JsonSerializerContext, JsonTypeInfo overloads
- AOT: add RedisContextJsonSerializerContext with all entity types registered
- AOT: replace TimeTickerEntityConverter with source-gen serialization
- Add [JsonInclude] on internal set entity properties for serializer visibility
- Add NodeHeartbeatPayload named type (replaces anonymous type)
- Add predicate filtering inside deserialization loop (less memory allocation)
- Add TickerQRedisOptionBuilder.JsonSerializerContext for user-provided AOT contexts
- Add comprehensive unit tests (32 persistence + 14 manager integration + 5 on-demand)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix TickerFunctionProvider.Build() empty TickerFunctions with concurrent test hosts (#784)
* test: add unit test for Build method stability after updating cron expressions
* test: add unit test for cron expression updates after initial build
* fix: initialize dictionaries with existing data in TickerFunctionProvider
* fix: add locking to function and request type registrations in TickerFunctionProvider
Build() is protected by _buildLock, but registration methods (RegisterFunctions, RegisterRequestType, RegisterRequestInfo, and UpdateCronExpressionsFromIConfiguration) mutate the same delegate fields via += without taking that lock. In concurrent host-startup scenarios, this can still lead to lost/late registrations (e.g., a cron-update callback added while another thread is building). Consider synchronizing registration updates with the same lock (or using an Interlocked.CompareExchange loop) so registrations and builds are atomic relative to each other.
* Source gen update (#794)
* Refactor source generator with templates, add ITickerFunction interface, MapTicker API, and Dashboard AOT support
Source Generator:
- Replace StringBuilder code generation with const string templates (Generation/Templates.cs)
- Extract MethodAnalyzer, ConstructorAnalyzer, InterfaceMethodAnalyzer into Analysis/
- Extract FactoryGenerator, FunctionRefsGenerator into Generation/
- Add TickerMethodModel, ConstructorModel, TickerFunctionInterfaceInfo models
- Generate TickerFunctions.g.cs with typed TickerFunctionRef per function
- Scan ITickerFunction/ITickerFunction<T> interface implementations
- Use global:: prefix for all type references (namespace-safe)
- Handle C# keyword aliases (string→System.String, int→System.Int32, byte[]→System.Byte[])
- Use collection initializer syntax in generated code
- Move ToGenericContextWithRequest to TickerQ.Utilities.TickerRequestProvider
TickerQ.Utilities:
- Add ITickerFunction, ITickerFunction<T>, ITickerFunctionBase interfaces
- Add TickerFunctionRef, TickerFunctionRef<T> structs for type-safe function references
- Add TickerFunctionBuilder<T> for fluent MapTicker configuration
- Add TickerFunctionProvider.Configure() for runtime config overrides
TickerQ:
- Add MapTicker<T>() extension for interface-based function registration
- Add MapTimeTicker() for lambda-based function registration
Dashboard AOT:
- Rewrite all endpoint handlers to accept only HttpContext (NativeAOT compatible)
- Replace Results.Json with WriteJson helper using JsonTypeInfo
- Rewrite JsonExampleGenerator to use JsonTypeInfo.Properties (zero reflection)
- Fix StringToByteArrayConverter to use JsonTypeInfo overloads
- Fix TickerDashboardRepository: Enum.GetValues<T>(), JsonTypeInfo for deserialization
- Remove DefaultJsonTypeInfoResolver from DashboardJsonOptions
- Add IsAotCompatible to Dashboard csproj
- Zero AOT warnings from Dashboard code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove interface scanning from source gen, add MapTickerGroup, DI-based registration
- Source generator no longer scans ITickerFunction implementations (only [TickerFunction] attributes)
- MapTicker<T>() now registers via IServiceCollection with DI (no reflection, AOT-safe)
- Add MapTickerGroup() with two styles: inline callback and variable
- Group prefixes function names: "GroupName.ClassName"
- Add TickerFunctionProvider.RegisterTypeMapping for type-safe manager lookups
- Add WithLifetime() default ServiceLifetime.Scoped (one instance per execution scope)
- Support name override: group.MapTicker<T>("CustomName")
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* added to managers.
* Added cron validator with normalizer
* AOT support: WithJsonContext, AOT-safe request serialization, SignalR and exception serialization
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Rename MapTimeTicker to MapTicker for lambda-based overloads
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add ITickerQueryable abstraction, rename MapTimeTicker to MapTicker, make TickerFunctionBuilder non-generic
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix the endpoints and missing persistence methods and pre-relase for … (#804)
* fix the endpoints and missing persistence methods and pre-relase for 10.2.5
* fixed the issue on tests.
* fix example results
* added redis tests to solution
* added 3.0 version beta
* Update version from 10.3.0-beta to 10.3.0
* Update logo image format from PNG to SVG
* Apply version-specific overrides for net9
* Fix _serviceProvider access level for net9 branch sync
Change _serviceProvider from private to protected in BasePersistenceProvider
to match main branch. Required by TickerEFCorePersistenceProvider which
accesses it for the new ITickerQueryable methods.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com>
Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com>
Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com>
Co-authored-by: jods <jods4@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com>
Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com>
Co-authored-by: EarlJester <shon3322@gmail.com>
Co-authored-by: stevewoj <steve.wojciechowski@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl>
Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com>
Co-authored-by: albert-miden <albert@miden.co>
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Rafael Câmara <52082556+RafaelJCamara@users.noreply.github.com>
Co-authored-by: Valiantsin Leushyts <levshits.l@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
albert-kunushevci
added a commit
that referenced
this pull request
Apr 13, 2026
* Fixed the issue with dead node release
* Fixed the scheduler to handle inline tasks and to not create deadlock on threads of TickerQ
* fixed the window time of picking tasks
* Fixed the task cancellation issue
* fixed the scheduler to show real time threads active
* Updated for the net10 support
* update to release version
* added release for net9
* added pattern to skip commits using comments on commit for cherry pick merge between branches
* remove unecessary build command
* fixed the sync
* updated cherry detections
* try merge based on commit
* Fixed the json options to be isolated (#375)
* Fix/schedulerbackground (#376)
* Fixed the scheduler background to Task.Delay since the Peridic Timer were skipping ticks on short interval with seconds.
* small refactor
* fixed the mixd up delete ticker
* beta version 17 release (#382)
* Feature/improvements (#386)
* Made improvements and new feature: request by default not using GZIP compression
* Added timezone dashboard support and other fix on features.
* Fixed the seefing data
* Update README.md
* Update README.md
* updated beta version
* Feature/new improvements (#397)
* Added some new features on dashboard and on demand running directly without giving pressure of background scheduler
* Added dispatch interfaces
* added pagination on machine names
* Added test coverage
* added examples
* Added sample sqlite for samples
* Added csproj fules for Sample data
* fixed the locking of immediate run ticker in safe for runcondition
* fiexed indexing, the scheduler on high run and memory persistence
* fixed dashboard path merge
* small fixes on manager
* Added migration changes for examples
* releas of stable version
* Update README.md
* Release of stable version.
* Fix schema assignment logic and add SetSchema method (#415)
* Fix schema assignment logic in UseTickerQDbContext and add SetSchema method
* Refactor UseTickerQDbContext to simplify schema assignment logic
* Add support for enabling/disabling background services (#413)
* Checkpoint from VS Code for coding agent session
* Remove documentation on separating job queueing from job processing
* Update Directory.Build.props
* Added logo locally
* Fix retry logic and add unit tests for ExecuteTaskAsync (#429)
* Add retry logic improvements and unit tests for ExecuteTaskAsync
* Refactor retry test setup to use SetupRetryTestFixture for consistency
* fix: namespace conflicts for ModuleInitializer attribute in TickerQIncrementalSourceGenerator (#433)
* Update Directory.Build.props
* Update Directory.Build.props
* fix update ExecutionTime for CronTickerOccurrence (#461)
* feat: add configurable policy name for Host auth (#482)
* Initial plan
* Add configurable authorization policy name for Host mode
Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com>
* Refactor: Make policy an optional parameter to WithHostAuthentication
Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com>
* fix: Host auth. should not depend on Authorization header (#481)
Fixes #446
* [Feature] Remove ASP.NET Core dependency from TickerQ.Utilities to support all .NET platforms (#480)
* Removes ASP.NET Core dependency
Generalizes TickerQ to support non-ASP.NET Core environments like console applications and worker services.
Refactors extension methods to utilize IHost and IServiceProvider instead of IApplicationBuilder, decoupling the core library from ASP.NET Core.
Updates dependencies to use Microsoft.Extensions.* packages directly, using defined DotNetVersion.
* Resolves NuGet version mismatches
Ensures consistent NuGet package versions by defining the .NET package version as a variable in the Directory.Build.props file and using it across all project files.
This maintains consistency of dependency versions across all projects.
---------
Co-authored-by: EarlJester <shon3322@gmail.com>
* Fix missing await to AuthenticateHostAsync call (#494)
* Fix #497 (#503)
* Fix stackoverflow in JsonExampleGenerator (#519)
* Addded unit tests to cover existing JsonExampleGenerator functionality. Prevent infinite recursion in JsonExampleGenerator.
* Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/TickerQ.Dashboard/TickerQ.Dashboard.csproj
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/TickerQ.Dashboard/Infrastructure/Dashboard/JsonExampleGenerator.cs
good catch
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Feature/tickerq hub (#508)
* Added persistence for the redis.
* TickerQHub integration
* added ready-to-deploy the new version
* pre-release
* fix references
* Add missing ASP.NET Core package references to TickerQ.SDK (#537)
Added package references for ASP.NET Core extension packages to resolve
CS0234 build errors when deploying. The SDK uses ASP.NET Core types
(IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing
the required package references.
Added packages:
- Microsoft.AspNetCore.Http.Abstractions
- Microsoft.AspNetCore.Http.Results
- Microsoft.AspNetCore.Routing
- Microsoft.AspNetCore.Mvc.Abstractions
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
Co-authored-by: Claude <noreply@anthropic.com>
* Claude/fix aspnetcore namespace xuvot (#540)
* Add missing ASP.NET Core package references to TickerQ.SDK
Added package references for ASP.NET Core extension packages to resolve
CS0234 build errors when deploying. The SDK uses ASP.NET Core types
(IEndpointRouteBuilder, IEndpointFilter, Results, etc.) but was missing
the required package references.
Added packages:
- Microsoft.AspNetCore.Http.Abstractions
- Microsoft.AspNetCore.Http.Results
- Microsoft.AspNetCore.Routing
- Microsoft.AspNetCore.Mvc.Abstractions
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix ASP.NET Core namespace errors by using Web SDK
Changed TickerQ.SDK to use Microsoft.NET.Sdk.Web with OutputType=Library
instead of adding individual ASP.NET Core packages. The individual packages
(Microsoft.AspNetCore.Http.Abstractions, etc.) are not published for .NET 5+
and are only available through the shared framework.
Using Sdk.Web with OutputType=Library provides access to ASP.NET Core types
(IEndpointRouteBuilder, IEndpointFilter, Results, etc.) while still
producing a class library output.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Remove invalid ASP.NET Core package references (#541)
The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.)
don't exist as standalone NuGet packages for .NET 5+. They were discontinued
after .NET Core 2.x and are only available through the shared framework.
Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are
automatically available through the implicit framework reference. The
explicit package references were causing NU1102 errors during restore.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
Co-authored-by: Claude <noreply@anthropic.com>
* Claude/remove invalid aspnetcore packages xuvot (#542)
* Remove invalid ASP.NET Core package references
The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.)
don't exist as standalone NuGet packages for .NET 5+. They were discontinued
after .NET Core 2.x and are only available through the shared framework.
Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are
automatically available through the implicit framework reference. The
explicit package references were causing NU1102 errors during restore.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types
Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library
to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are
required for the dashboard middleware and endpoints.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types
Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library
to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.)
that are required for the remote execution endpoints.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Claude/remove invalid aspnetcore packages xuvot (#543)
* Remove invalid ASP.NET Core package references
The ASP.NET Core packages (Microsoft.AspNetCore.Http.Abstractions, etc.)
don't exist as standalone NuGet packages for .NET 5+. They were discontinued
after .NET Core 2.x and are only available through the shared framework.
Since TickerQ.SDK already uses Microsoft.NET.Sdk.Web, these types are
automatically available through the implicit framework reference. The
explicit package references were causing NU1102 errors during restore.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix TickerQ.Dashboard to use Web SDK for ASP.NET Core types
Changed TickerQ.Dashboard to use Microsoft.NET.Sdk.Web with OutputType=Library
to provide access to ASP.NET Core types (IApplicationBuilder, etc.) that are
required for the dashboard middleware and endpoints.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix TickerQ.RemoteExecutor to use Web SDK for ASP.NET Core types
Changed TickerQ.RemoteExecutor to use Microsoft.NET.Sdk.Web with OutputType=Library
to provide access to ASP.NET Core types (IEndpointRouteBuilder, IEndpointFilter, etc.)
that are required for the remote execution endpoints.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
* Fix IApplicationBuilder cast in Dashboard ServiceExtensions
The UseDashboardApplication callback receives an object (since TickerQ.Utilities
doesn't have ASP.NET Core dependencies), so we need to explicitly cast it to
IApplicationBuilder before calling extension methods on it.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Enable NuGet package generation for Web SDK projects (#546)
Microsoft.NET.Sdk.Web sets IsPackable=false by default. Added explicit
IsPackable=true to TickerQ.SDK, TickerQ.RemoteExecutor, and TickerQ.Dashboard
to ensure NuGet packages are generated during build.
https://claude.ai/code/session_01XaNrB2LuCkTM6FRjxuUyt7
Co-authored-by: Claude <noreply@anthropic.com>
* Fix #511 and #517: null reference and orphaned cron ticker bugs (#549)
- #511: Add null check for CachedDelegate in RunContextFunctionAsync with
a clear InvalidOperationException message instead of cryptic NRE
- #517: Fix orphaned cron tickers not being cleaned up on restart when
their expression was edited via the dashboard. The dashboard update
wipes InitIdentifier, causing the seeded-only cleanup to miss them.
Now checks all cron tickers against TickerFunctionProvider.TickerFunctions
to remove any whose function no longer exists in code. Applied to
EF Core, In-Memory, and Redis persistence providers.
https://claude.ai/code/session_015JykuFsRPUz3q19jxYh7uy
Co-authored-by: Claude <noreply@anthropic.com>
* Fix thread-safety bugs, resource leaks, and scheduling issues (#550)
* Fix thread-safety bugs, resource leaks, and scheduling issues across core components
Addresses multiple concurrency bugs, resource disposal issues, and adds
performance optimizations across the scheduler, cancellation, caching,
and persistence layers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add tests for SafeCancellationTokenSource, CronScheduleCache DST handling, cancellation manager, and task scheduler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix BindingFlags in SetProperty_Reinitializes test — ParametersToUpdate is public
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* added extension method for WebApplication
* pre-release
* fix and pre-release
* removed the not-needed reference from the Tickerq.
* fixed based on the tickerq architecture.
* update version
* fix and pre-release...
* release a stable version
* release a stable version along with the new libs for the hub.
* Fix .NET 9+ EF Core query failures caused by ReadOnlySpan array.Contains() (#574)
On .NET 9+, the compiler resolves array.Contains() to
MemoryExtensions.Contains() which uses ReadOnlySpan<T>. EF Core cannot
translate ReadOnlySpan<T> in LINQ expressions, causing
InvalidOperationException at runtime for all persistence queries that
filter by arrays of IDs.
Convert all Guid[] and string[] parameters to List<T> before use in
EF Core LINQ .Where() clauses so the compiler resolves to
List<T>.Contains() which EF Core can translate to SQL IN clauses.
Fixes #460, #462, #465, #466, #470
https://claude.ai/code/session_01JLAicT6LCaCbcR8aZhNri2
Co-authored-by: Claude <noreply@anthropic.com>
* fix the dashboard...
* Add comprehensive unit tests for core TickerQ components (#582)
New test files covering must-have areas that were previously untested:
- TickerExecutionTaskHandlerTests: success/failure/cancellation/terminate
execution paths, parent-child execution with RunCondition logic,
instrumentation logging, null delegate handling
- TickerQDispatcherTests: constructor guards, dispatch delegation,
empty/null context handling, priority routing
- TerminateExecutionExceptionTests: all constructors, status defaults,
inner exception preservation
- SoftSchedulerNotifyDebounceTests: notify callback, duplicate suppression,
flush, dispose idempotency, zero-value handling
- RestartThrottleManagerTests: debounce coalescing, timer reset, dispose safety
- WorkItemTests: constructor validation, null guard, token handling
- PaginationResultTests: computed properties (TotalPages, HasPreviousPage,
HasNextPage, FirstItemIndex, LastItemIndex), edge cases
- TickerResultTests: all internal constructors via reflection
- TickerHelperTests: serialization with/without GZip, round-trip,
custom JSON options, complex objects
https://claude.ai/code/session_01AmFBuKfp4VyfuRCviW7meu
Co-authored-by: Claude <noreply@anthropic.com>
* added rickerq hub to readme file.
* Fix authorize against HostAuthorizationPolicy when set (#591)
* Add host policy support to AuthService and new unit tests
Refactored AuthenticateHostAsync to support host authorization
policies using IAuthorizationService. Added comprehensive
unit tests for host mode authentication, including policy
checks and multiple identity scenarios.
* Rename test method for clarity in AuthServiceHostTests
Renamed AuthenticateAsync_HostMode_WithMultipleIdentities_SecondaryIdentitySatisfiesPolicy_ReturnsSuccessWithSecondaryName to ...ReturnsSuccess for improved clarity and consistency. No changes to the test logic or implementation.
* Update AuthService to pass HttpContext as auth resource
Changed the resource parameter in AuthorizeAsync from null to the current HttpContext. This enables authorization policies to access request-specific context during evaluation, allowing for more flexible and informed authorization decisions.
* Added dashboard group name for the openapi (#585)
* fixed unit testing and issue of (#586)
* added the sample for worker service
* fix issue 522 (#587)
* Add JSON-serializable tracking fields to TimeTickerEntity (#609)
* Add JSON-serializable tracking fields to TimeTickerEntity
Added Status, LockHolder, LockedAt, ExecutedAt, ExceptionMessage, SkippedReason, ElapsedTime, RetryCount, and ParentId to TimeTickerEntity<TTicker>, all with [JsonInclude] for serialization. Enhances tracking and state visibility.
* Add custom JSON converter for TimeTickerEntity
Introduced TimeTickerEntityConverter for explicit serialization/deserialization. Registered converter in Redis provider. Removed redundant [JsonInclude] attributes. Improved property handling and query readability in persistence logic.
* revert that
* Delete samples/TickerQ.Sample.WebApi/Properties/launchSettings.json
* Delete src/TickerQ.Dashboard/Properties/launchSettings.json
* Delete src/TickerQ.RemoteExecutor/Properties/launchSettings.json
* Delete src/TickerQ.SDK/Properties/launchSettings.json
* Delete tests/TickerQ.Tests.WebApi/Properties/launchSettings.json
* Update .gitignore to remove Aspire project entries
Removed ignore rules for sample Aspire projects.
* revert
* revert
* Fix UseApplicationDbContext implementation #498 (#590)
* Fix UseApplicationDbContext implementation
* Remove unnecessary comment
* Move to async implementation
* Fix tests
* Add sample project for ApplicationDbContext usage
* added unit tests for more edge cases coverage. (#623)
* Improve branch sync workflow, migrate to slnx, and clean up repo (#628)
- Rewrite sync-version-branches.yml with .sync-exclude support, DotNetVersion fix, conflict auto-resolution, and PR comments when excluded files are modified
- Add .sync-exclude listing version-specific EF Core files and TickerQ.sln
- Migrate TickerQ.sln to TickerQ.slnx (XML-based, .NET 10+)
- Remove tracked SQLite db files (tickerq-console.db*)
- Update .gitignore: add *.db, tmpgen/, *.DotSettings.user
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix EF Core type mapping error for MySQL providers in MigrateDefinedCronTickers (#631)
Use List<string> instead of HashSet<string> for the allRegisteredFunctions
collection used in LINQ-to-SQL queries. Some EF Core providers (Devart MySQL,
Oracle MySQL Connector) don't assign type mappings to HashSet parameters in
IN expressions, causing InvalidOperationException on EF Core 10.
Fixes #621, #624
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add IsEnabled property to CronTickerEntity with full-stack support (#632)
Add ability to enable/disable cron tickers without deleting them.
Disabled tickers are filtered out of the scheduling pipeline while
remaining visible in the dashboard. Includes toggle endpoint, dashboard
UI with confirmation dialog, and fixes flaky test caused by parallel
test execution sharing static TickerCancellationTokenManager state.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix TickerModelCustomizer not applying configured schema (#635)
TickerModelCustomizer was calling configurations without passing the
schema, causing migrations to always use the default "ticker" schema
instead of the one set via SetSchema(). Now resolves the schema from
TickerQEfCoreOptionBuilder, matching how TickerQDbContext does it.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Replace reflection-based JSON serialization in Dashboard with source … (#638)
* Replace reflection-based JSON serialization in Dashboard with source generation
Adds DashboardJsonSerializerContext with [JsonSerializable] for all Dashboard
types, replacing anonymous objects in endpoints with named DTOs. Wires up
TypeInfoResolverChain with source-gen context + DefaultJsonTypeInfoResolver
fallback for user-defined entity types. Fixes StringToByteArrayConverter to
use JsonDocument.Parse instead of reflection-based Deserialize<object>.
Supports projects using JsonSerializerIsReflectionEnabledByDefault=false.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix reflection-free scenarios: register Guid[] in source-gen context, configure ASP.NET HTTP JSON options, and avoid reflection in StringToByteArrayConverter
- Add Guid[] to DashboardJsonSerializerContext for minimal API endpoint parameter binding
- Register DashboardJsonSerializerContext in ConfigureHttpJsonOptions for app-level serialization
- Serialize JsonElement via options chain in StringToByteArrayConverter instead of TickerHelper.RequestJsonSerializerOptions
- Add TickerQ.Sample.Dashboard.ReflectionFree sample project
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Dashboard failing with old Startup.cs pattern (IHost not implementing IApplicationBuilder) (#641)
UseTickerQ() passes IHost to DashboardApplicationAction, but in the old
Host.CreateDefaultBuilder + Startup.cs pattern, IHost does not implement
IApplicationBuilder (only WebApplication does in the new pattern).
Fix: Register an IStartupFilter that injects Dashboard middleware into the
pipeline when the web host builds it. This works in both patterns:
- New pattern: UseDashboardDelegate applies directly (IHost is IApplicationBuilder),
and sets MiddlewareApplied flag to prevent IStartupFilter from duplicating.
- Old pattern: UseDashboardDelegate skips (IHost is not IApplicationBuilder),
and IStartupFilter applies the middleware when the pipeline is built.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Relax abstractions version constraints and fix sync workflow version handling (#645)
- Add DotNetAbstractionsVersion property with open range [8.0.0,) to
allow consumers to use newer Microsoft.Extensions.*Abstractions packages
- Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions
- Fix sync workflow to handle any major version dynamically instead of
hardcoded patterns (e.g. 10.x → 8.x now works correctly)
- Preserve DotNetAbstractionsVersion from target branch during sync
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Relax abstractions version constraints and fix sync workflow version handling (#647)
- Add DotNetAbstractionsVersion property with open range [8.0.0,) to
allow consumers to use newer Microsoft.Extensions.*Abstractions packages
- Update all csproj files to use $(DotNetAbstractionsVersion) for abstractions
- Fix sync workflow to handle any major version dynamically instead of
hardcoded patterns (e.g. 10.x → 8.x now works correctly)
- Preserve DotNetAbstractionsVersion from target branch during sync
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Eliminate inline scripts from Dashboard for CSP script-src 'self' support (#648)
Move all inline JavaScript to external files served via middleware,
allowing the Dashboard to work with strict Content-Security-Policy
headers that block 'unsafe-inline'.
- Extract Vite's preload script from embedded index.html at startup
and serve it as __tickerq-preload.js (cached, before auth)
- Serve runtime config (window.TickerQConfig, window.__dynamic_base__)
as __tickerq-config.js endpoint (dynamic, before auth)
- Replace inline <script> injection with external <script src="...">
references in the HTML template
- Remove SanitizeForInlineScript (no longer needed for external files)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Dashboard BasePath not working with UsePathBase (#332) (#651)
Replace app.Map() with PathBase-aware routing middleware that strips the
PathBase prefix from basePath at request time, so the dashboard works
regardless of middleware ordering or whether the user includes the PathBase
prefix in SetBasePath(). Also fix CombinePathBase to detect when PathBase
already ends with basePath (inside a Map branch) to prevent doubled paths
in frontend URLs.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix design-time DbContext failure when TickerQEfCoreOptionBuilder is unavailable (#457) (#652)
Make OnModelCreating and TickerModelCustomizer null-safe by falling back
to Constants.DefaultSchema when the option builder service is not
resolvable (design-time migrations, integration tests, Aspire).
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix source generator namespace sanitization for assemblies with invalid C# identifier characters (#303) (#657)
Use RootNamespace build property when available, falling back to sanitized
assembly name (replacing dashes and other invalid characters with underscores).
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix empty request deserialization throwing JsonException (#463) (#658)
Add null/empty guard in ReadTickerRequest<T> to return default
instead of throwing when no request data is provided.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date format to use browser locale (#581) (#663)
Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using
the browser's locale, so dates display in the user's preferred format.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date format to use locale-independent YYYY-MM-DD (#666)
* Fix dashboard date format to use browser locale (#581)
Replace hardcoded DD.MM.YYYY format with Intl.DateTimeFormat using
the browser's locale, so dates display in the user's preferred format.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date format to use consistent locale-independent YYYY-MM-DD format (#581)
Replace locale-dependent Intl.DateTimeFormat(undefined) with formatToParts
using en-CA locale for consistent YYYY-MM-DD HH:mm:ss display regardless
of the user's browser locale. Also fixes ChainJobsModal toLocaleDateString.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add per-function concurrency control via maxConcurrency parameter (#670)
* Add per-function concurrency control via maxConcurrency attribute parameter (#458)
Adds a `maxConcurrency` parameter to `[TickerFunction]` that limits how many
instances of a specific function can execute concurrently. When set to 0 (default),
concurrency is unlimited (preserving backward compatibility). The limit is enforced
via a per-function SemaphoreSlim in the dispatcher, queuing excess work instead of
skipping it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add tests for per-function concurrency gate and dispatcher concurrency behavior
Tests cover:
- ConcurrencyGate: null for unlimited, semaphore creation, caching, independence
- Dispatcher: semaphore acquire/release, release on exception, independent
semaphores per function, serialized execution with maxConcurrency=1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Apply concurrency gate to all QueueAsync call sites
Previously only TickerQDispatcher and FallbackBackgroundService used the
concurrency gate. This adds it to TickerQSchedulerBackgroundService (the
main scheduler loop) and SdkExecutionEndpoint (SDK remote execution).
Also moves ITickerFunctionConcurrencyGate to TickerQ.Utilities so the SDK
project can resolve it from DI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add scheduler concurrency gate integration tests
Verify that TickerQSchedulerBackgroundService correctly uses the
concurrency gate when queuing tasks: semaphore acquire/release on
success, release on exception, and no semaphore for unlimited functions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Centralize test project versions for cross-branch compatibility (#673)
* Centralize test project versions via Directory.Build.props
Replace hardcoded TargetFramework and package versions in test projects
with MSBuild variables (DotNetVersion), matching the pattern used by src
projects. This ensures version compatibility when backporting to v8/v9.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add EntityFrameworkCore test project to PR workflow
The pr.yaml workflow only built and ran TickerQ.Tests. Added
TickerQ.EntityFrameworkCore.Tests to both the build and test steps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix design-time DbContext tests failing due to EF Core GetService throw
EF Core's GetService<T>() extension throws InvalidOperationException
when the service is unresolvable, so the null-conditional (?.) from
#652 never executes. Use try-catch to fall back to DefaultSchema.
Also add EnableServiceProviderCaching(false) to prevent model cache
pollution across tests with the same DbContext type.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix AddStackExchangeRedis overriding EF Core persistence provider (#676)
* Fix AddStackExchangeRedis overriding EF Core persistence provider (#669)
Change Redis persistence registration to TryAddSingleton so EF Core's
AddSingleton takes precedence regardless of registration order. Move
in-memory provider registration after external providers as a
TryAddSingleton fallback. Add dedicated Redis test project with
registration precedence tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add functional tests for persistence provider CRUD via managers and DI
Exercise ITimeTickerManager, ICronTickerManager, and
ITickerPersistenceProvider end-to-end through in-memory, EF Core,
and EF Core + Redis configurations. Add InternalsVisibleTo for the
new test project.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add concurrency and locking tests for persistence providers
Test lock acquisition, optimistic concurrency, dead node recovery,
concurrent multi-node access, cron occurrence locking, and
per-function concurrency gate (serialized/parallel execution,
exception safety).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use atomic Lua scripts for Redis acquire/release/recovery operations
Replace all non-atomic read-check-write patterns with Redis Lua scripts
that execute atomically (single-threaded), eliminating TOCTOU race
conditions in multi-node deployments. This brings Redis provider parity
with EF Core's atomic ExecuteUpdateAsync + WHERE clause guarantees.
Three Lua scripts: AcquireScript (status/holder/updatedAt check + lock),
ReleaseScript (status/holder check + unlock), RecoverDeadNodeScript
(dead node holder match + reset to Idle).
10 methods updated: QueueTimeTickers, QueueTimedOutTimeTickers,
AcquireImmediateTimeTickersAsync, ReleaseAcquiredTimeTickers,
ReleaseDeadNodeTimeTickerResources, QueueCronTickerOccurrences,
QueueTimedOutCronTickerOccurrences, AcquireImmediateCronOccurrencesAsync,
ReleaseAcquiredCronTickerOccurrences, ReleaseDeadNodeOccurrenceResources.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Redis registration test and remove redundant Hosting.Abstractions reference (#680)
- Changed Redis registration test to check service descriptor instead
of resolving the provider, which triggered a real Redis connection
and failed in CI environments without Redis.
- Removed redundant Microsoft.Extensions.Hosting.Abstractions package
reference from TickerQ.csproj — it's already a transitive dependency
from TickerQ.Utilities, and the explicit lower-bound reference caused
NU1605 package downgrade errors.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date formatting by timezone region and cron ticker toggle bug (#683)
- Date format now adapts to selected timezone: EU (dd/MM/yyyy), US (MM/dd/yyyy), ISO (yyyy-MM-dd)
- Applied timezone-aware formatting to all date displays including tables, graphs, and date picker
- Fixed cron ticker enable/disable dialog showing inverted text
- Fixed Redis persistence not filtering disabled cron tickers in GetAllCronTickerExpressions
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* new release 10.2.0
* Simplify EF Core DbContext session pattern (#688)
* Simplify EF Core DbContext session pattern and remove dead validation
- Remove dead originalDescriptor lookup and throw in UseApplicationDbContext
(the variable was unused after PR #590 switched to IDbContextOptionsConfiguration)
- Replace ITickerDbContextFactory/ITickerDbContextSession interfaces with a
simpler DbContextLease struct that handles both IDbContextFactory and
scoped DbContext resolution
- Remove ITickerDbContextFactory DI registration — BasePersistenceProvider
now takes IServiceProvider directly and creates leases via helper methods
- Addresses feedback from @jods4 on PR #590
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update EF Core tests to use IServiceProvider instead of removed ITickerDbContextFactory
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add unit tests for DbContextLease resolution across DI configurations (#691)
Tests cover factory path, scoped path, pooled factory, precedence,
instance isolation, dispose behavior, change tracking isolation,
and error cases when no DbContext is registered.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* release for fix/ef-core-dbcontext-session-cleanup
* Add head-to-head BenchmarkDotNet comparisons vs Hangfire & Quartz (#697)
Includes 6 comparison benchmarks (cron parsing, job creation, serialization,
startup registration, delegate invocation, concurrent throughput) plus 7
internal TickerQ micro-benchmarks. All runnable via `dotnet run -c Release`.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Register scoped DbContext from factory for direct injection (#700) (#702)
* Register scoped DbContext from factory for direct injection (#700)
UseTickerQDbContext only registered IDbContextFactory<TContext> but not
TContext itself, preventing users from injecting the DbContext directly.
Add a scoped registration that creates instances from the factory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* new fix on db context scope create, release: 10.2.1
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder (#709)
* Restructure hub projects: move RemoteExecutor and SDKs into hub/ folder
- Move TickerQ.RemoteExecutor to hub/remoteExecutor/
- Move TickerQ.SDK (.NET) to hub/sdks/dotnet/
- Add TickerQ Node.js SDK to hub/sdks/node/ with full source, README, and LICENSE
- Add hub/Directory.Build.props with corrected icon.jpg path for NuGet packaging
- Add .gitignore for Node.js SDK
- Update src.sln project references to new paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix TickerQ.slnx project paths for hub restructuring
Update RemoteExecutor and SDK paths in root slnx to match the new
hub/ folder structure, fixing CI build and test failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix build.yml project paths for hub restructuring
Update SDK and RemoteExecutor build/pack paths from src/ to hub/
to match the new folder structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Add CLA workflow, CLA document, and contributing guidelines (#722)
- Add CLA.md with copyright/patent license grants for contributors
- Add CONTRIBUTING.md with development setup and contribution process
- Add GitHub Actions CLA workflow using contributor-assistant/github-action
- Allowlist dependabot, github-actions, and renovate bots
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Scope CLA workflow to main branch only
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update README.md (#726)
* Rewrite README: cleaner structure, feature highlights, contributors section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Discord badge to use static badge instead of invalid server ID
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update README tagline and subtitle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update copyright to Arcenox LLC, add Authors/Copyright to NuGet metadata
- Update LICENSE, CLA.md, README.md to reference Arcenox LLC
- Add Authors and Copyright tags to Directory.Build.props
- Clean trailing whitespace in LICENSE
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add SECURITY.md with vulnerability reporting policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Rewrite branch sync from cherry-pick to merge-based approach (#744)
- Replace cherry-pick workflow with merge-based sync (handles renames/deletions naturally)
- Add .sync-overrides config for generic version replacement rules
- Apply version overrides from config instead of hardcoded sed commands
- Post PR comment with sync details (restored files + version overrides applied)
- Auto-resolve conflicts: excluded files keep target, everything else takes main
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix sync-overrides loading from target branch instead of main
The .sync-overrides file only exists on main, but was being loaded
from the target branch (net8/net9) before the merge. Load it from
main using git show instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix sync workflow: load exclude/overrides from main, escape sed regex
- Load .sync-exclude from main (not target branch) so it's always up to date
- Escape regex special characters in sed replacements (fixes [x.0.0,y.0.0) values)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix version-range sed regex error by using awk for replacements
Values like [8.0.0,9.0.0) contain regex special chars that break sed.
Use awk string matching instead which handles literal characters.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix sync builds: use $(DotNetVersion) for packages, detect .NET version in CI
- Replace hardcoded FlexLabs.Upsert version with $(DotNetVersion)
- Replace hardcoded EF Core Sqlite version in benchmarks with $(DotNetVersion)
- Add overrides for tests/Directory.Build.props and sample/benchmark csproj files
- Detect .NET version and solution file dynamically in PR and build workflows
- Fix PR comment table formatting (property column was empty)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Centralize version props in src/Directory.Build.props
- src/Directory.Build.props is the single source of truth for
TargetFramework, Version, DotNetVersion, DotNetAbstractionsVersion
- tests/samples/benchmarks import from src/ and disable packaging
- Replace all hardcoded package versions with $(DotNetVersion)
- Simplify .sync-overrides to only override src/Directory.Build.props
- Detect .NET version dynamically in PR and build workflows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add CustomizerServiceDescriptor.cs to .sync-exclude
Uses IDbContextOptionsConfiguration<T> which only exists in EF Core 10.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add retry for PR comment in sync workflow
Race condition: PR may not be indexed when comment step runs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard WebSocket 405 when host uses MapStaticAssets (#456) (#723)
Clear host-level endpoint routing state in MapPathBaseAware before
entering the dashboard branch pipeline. When host-level Map*() calls
(e.g. MapStaticAssets().ShortCircuit()) activate endpoint routing,
the EndpointRoutingMiddleware may set an endpoint on the HttpContext.
The branch's own UseRouting() then skips evaluation (it short-circuits
when GetEndpoint() is non-null), causing SignalR negotiate/WebSocket
requests to hit the wrong endpoint and return 405.
The fix calls SetEndpoint(null) and clears RouteValues when the
dashboard base path matches, ensuring the branch's routing middleware
re-evaluates against dashboard endpoints.
Closes #456
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix Oracle-incompatible boolean default in CronTicker migration (#716) (#721)
Replace HasDefaultValue(true) with HasDefaultValueSql("1") on the
IsEnabled property in CronTickerConfigurations. The former emits
DEFAULT True in migration SQL, which is invalid on Oracle (ORA-00904).
HasDefaultValueSql("1") produces DEFAULT 1, valid across SQL Server,
PostgreSQL, SQLite, and Oracle. HasSentinel(true) ensures EF Core
still sends explicit false values instead of deferring to the DB default.
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Switch build and sync workflows to trigger on release
- build.yml: trigger on release publish instead of push to main/net8/net9
- sync-version-branches.yml: trigger on release publish instead of push to main
- Both keep workflow_dispatch as manual fallback
- Updated Discord notification for release context
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add test step to release build workflow
Tests run before packaging — if tests fail, no NuGet packages are published.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Source Link and symbol package support (#743)
* Add Source Link and symbol package support
- Enable Source Link with Microsoft.SourceLink.GitHub for debugger source stepping
- Generate .snupkg symbol packages alongside .nupkg
- Enable deterministic builds and CI build flag
- Embed untracked sources for complete debugging experience
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix sync-exclude, remove src/src.sln, organize TickerQ.slnx hub folder
- Fix .sync-exclude: TickerQ.sln → TickerQ.slnx (correct filename)
- Remove src/src.sln (replaced by TickerQ.slnx on main)
- Move hub projects to dedicated /hub/ folder in TickerQ.slnx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add src/src.sln to sync-exclude to protect it on net8/net9 branches
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix dashboard date/time display for Windows timezone IDs (#717) (#719)
Convert Windows timezone IDs (e.g. "Eastern Standard Time") to IANA
format (e.g. "America/New_York") before sending to the frontend, so
Intl.DateTimeFormat can correctly render dates in the configured
scheduler timezone. Also add defensive fallback in the frontend
formatDate() for invalid timezone IDs, and Windows timezone ID
pattern matching in getDateFormatRegion() for correct US/EU date
format selection.
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Skip TickerQ initialization in design-time tools (#712) (#763)
* Skip TickerQ initialization when running inside design-time tools (#712)
Build-time tools like dotnet-getdocument (used by
Microsoft.Extensions.ApiDescription.Server for OpenAPI generation)
invoke Program.Main to build the host, which triggers UseTickerQ →
InitializeTickerQ → SeedDefinedCronTickers. This causes database
queries in a context where no valid connection string exists, crashing
the build.
Add an Assembly.GetEntryAssembly() guard that detects dotnet-* tool
entry assemblies and short-circuits InitializeTickerQ before any
DB-touching or background service initialization occurs.
Closes #712
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Defer TickerQ initialization to host lifecycle instead of inline UseTickerQ (#712)
Replace the Assembly.GetEntryAssembly() heuristic with a proper lifecycle-based
approach: move all I/O-bound initialization (function discovery, DB seeding,
external provider startup) from inline UseTickerQ into a dedicated
TickerQInitializerHostedService that runs during host.StartAsync().
Design-time tools (dotnet-getdocument, dotnet-ef, etc.) build the host but
never start it, so the hosted service naturally never runs — no heuristics needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix TickerFunctionProvider Build() race condition and add startup validation (#764)
- Add lock to Build() so concurrent hosts (e.g. WebApplicationFactory tests)
don't overwrite a populated FrozenDictionary with an empty one (fixes #705)
- Initialize static FrozenDictionary fields to .Empty instead of null to
prevent NullReferenceException when UseTickerQ() is not called
- Add IsBuilt flag to distinguish "UseTickerQ() not called" from
"no [TickerFunction] methods found"
- Add TickerQStartupValidator IHostedService that warns at startup when
UseTickerQ() is missing or no ticker functions are registered
- Update test ResetProvider() to use FrozenDictionary.Empty and reset IsBuilt
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Bump version to 10.2.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix build pipeline: restore only build targets, not samples
The sample project uses PackageReference with $(Version) which resolves
to the version being built. Restoring the full solution fails because
the package isn't published yet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Switch Sample.WorkerService from PackageReference to ProjectReference
Fixes sync build failures on net8/net9 branches where $(Version) resolved
to a version that doesn't exist on NuGet yet. All samples now consistently
use ProjectReference.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add UseAuthorization() to dashboard branch pipeline for Host auth (#408) (#773)
When WithHostAuthentication() is configured, dashboard endpoints use
RequireAuthorization() metadata. ASP.NET Core's EndpointMiddleware throws
InvalidOperationException if no AuthorizationMiddleware exists between
UseRouting() and UseEndpoints(). The host app's UseAuthorization() does
not propagate into Map() branches, so the dashboard branch needs its own.
Closes #408
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Bump version to 10.2.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add GitHub issue templates for bug reports, features, and questions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix PostgreSQL incompatible boolean default in CronTicker (#779)
* Fix PostgreSQL incompatible boolean default in CronTicker (#778)
Replace HasDefaultValueSql("1") with HasDefaultValue(true) so EF Core
translates the CLR boolean into the correct SQL literal for each
provider (1 for SQL Server/SQLite, TRUE for PostgreSQL, appropriate
value for Oracle). The raw SQL literal "1" is invalid for PostgreSQL
boolean columns, causing migration failure with error 42804.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Use CLR-side default for CronTicker.IsEnabled instead of DB default
Remove HasDefaultValue(true) and HasSentinel(true) from the EF
configuration; the C# property initializer (= true) is sufficient.
EF Core always includes the property in INSERT/UPDATE SQL, so no
provider-specific SQL default translation is needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Adjust WebAPI sample with dashboard integration. (#777)
* Update version from 10.2.4 to 10.2.5
* feat: Simplify host authentication by removing direct access key input and updating UI/logic for a click-to-authenticate flow. (#786)
* Fix startup cron occurrence duplicate scheduling (#776) (#785)
* Fix startup cron occurrence duplicate scheduling (#776)
At startup, past-due cron occurrences left over from a previous
application lifecycle were being caught up by the fallback service,
causing unexpected duplicate executions. This was most visible when
stopping and restarting the application — the cron job would fire
immediately for the missed slot AND schedule normally for the next
slot.
The fix adds a startup cleanup step that marks stale past-due
occurrences (ExecutionTime more than 5 seconds old, still in
Idle/Queued status) as Skipped before the scheduler and fallback
services begin. This prevents the fallback from catching up
occurrences from a previous lifecycle while preserving normal
fallback behavior for the current lifecycle.
The 5-second grace period ensures that very recent occurrences
(e.g. from a sub-second restart) are not incorrectly skipped.
Closes #776
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Refactor stale cron occurrence cleanup into opt-in configurable option
Make stale-cron-occurrence skipping disabled by default (threshold = Zero)
and expose SkipStaleCronOccurrencesOnStartup() on TickerOptionsBuilder as
the primary opt-in API. The threshold is now passed through the full call
chain instead of being hardcoded in persistence providers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Refactor Redis persistence provider: extract helpers, base class, Lua scripts, AOT support (#793)
- Extract BaseRedisPersistenceProvider with core scheduler logic (mirrors EF Core pattern)
- Extract Helpers: RedisKeyBuilder, RedisIndexManager, RedisSerializer
- Move Lua scripts to embedded .lua files (Acquire, Release, RecoverDeadNode)
- AOT: use KEYS[]/ARGV[] notation, source-gen JsonSerializerContext, JsonTypeInfo overloads
- AOT: add RedisContextJsonSerializerContext with all entity types registered
- AOT: replace TimeTickerEntityConverter with source-gen serialization
- Add [JsonInclude] on internal set entity properties for serializer visibility
- Add NodeHeartbeatPayload named type (replaces anonymous type)
- Add predicate filtering inside deserialization loop (less memory allocation)
- Add TickerQRedisOptionBuilder.JsonSerializerContext for user-provided AOT contexts
- Add comprehensive unit tests (32 persistence + 14 manager integration + 5 on-demand)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix TickerFunctionProvider.Build() empty TickerFunctions with concurrent test hosts (#784)
* test: add unit test for Build method stability after updating cron expressions
* test: add unit test for cron expression updates after initial build
* fix: initialize dictionaries with existing data in TickerFunctionProvider
* fix: add locking to function and request type registrations in TickerFunctionProvider
Build() is protected by _buildLock, but registration methods (RegisterFunctions, RegisterRequestType, RegisterRequestInfo, and UpdateCronExpressionsFromIConfiguration) mutate the same delegate fields via += without taking that lock. In concurrent host-startup scenarios, this can still lead to lost/late registrations (e.g., a cron-update callback added while another thread is building). Consider synchronizing registration updates with the same lock (or using an Interlocked.CompareExchange loop) so registrations and builds are atomic relative to each other.
* Source gen update (#794)
* Refactor source generator with templates, add ITickerFunction interface, MapTicker API, and Dashboard AOT support
Source Generator:
- Replace StringBuilder code generation with const string templates (Generation/Templates.cs)
- Extract MethodAnalyzer, ConstructorAnalyzer, InterfaceMethodAnalyzer into Analysis/
- Extract FactoryGenerator, FunctionRefsGenerator into Generation/
- Add TickerMethodModel, ConstructorModel, TickerFunctionInterfaceInfo models
- Generate TickerFunctions.g.cs with typed TickerFunctionRef per function
- Scan ITickerFunction/ITickerFunction<T> interface implementations
- Use global:: prefix for all type references (namespace-safe)
- Handle C# keyword aliases (string→System.String, int→System.Int32, byte[]→System.Byte[])
- Use collection initializer syntax in generated code
- Move ToGenericContextWithRequest to TickerQ.Utilities.TickerRequestProvider
TickerQ.Utilities:
- Add ITickerFunction, ITickerFunction<T>, ITickerFunctionBase interfaces
- Add TickerFunctionRef, TickerFunctionRef<T> structs for type-safe function references
- Add TickerFunctionBuilder<T> for fluent MapTicker configuration
- Add TickerFunctionProvider.Configure() for runtime config overrides
TickerQ:
- Add MapTicker<T>() extension for interface-based function registration
- Add MapTimeTicker() for lambda-based function registration
Dashboard AOT:
- Rewrite all endpoint handlers to accept only HttpContext (NativeAOT compatible)
- Replace Results.Json with WriteJson helper using JsonTypeInfo
- Rewrite JsonExampleGenerator to use JsonTypeInfo.Properties (zero reflection)
- Fix StringToByteArrayConverter to use JsonTypeInfo overloads
- Fix TickerDashboardRepository: Enum.GetValues<T>(), JsonTypeInfo for deserialization
- Remove DefaultJsonTypeInfoResolver from DashboardJsonOptions
- Add IsAotCompatible to Dashboard csproj
- Zero AOT warnings from Dashboard code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove interface scanning from source gen, add MapTickerGroup, DI-based registration
- Source generator no longer scans ITickerFunction implementations (only [TickerFunction] attributes)
- MapTicker<T>() now registers via IServiceCollection with DI (no reflection, AOT-safe)
- Add MapTickerGroup() with two styles: inline callback and variable
- Group prefixes function names: "GroupName.ClassName"
- Add TickerFunctionProvider.RegisterTypeMapping for type-safe manager lookups
- Add WithLifetime() default ServiceLifetime.Scoped (one instance per execution scope)
- Support name override: group.MapTicker<T>("CustomName")
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* added to managers.
* Added cron validator with normalizer
* AOT support: WithJsonContext, AOT-safe request serialization, SignalR and exception serialization
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Rename MapTimeTicker to MapTicker for lambda-based overloads
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add ITickerQueryable abstraction, rename MapTimeTicker to MapTicker, make TickerFunctionBuilder non-generic
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix the endpoints and missing persistence methods and pre-relase for … (#804)
* fix the endpoints and missing persistence methods and pre-relase for 10.2.5
* fixed the issue on tests.
* fix example results
* added redis tests to solution
* added 3.0 version beta
* Update version from 10.3.0-beta to 10.3.0
* Update logo image format from PNG to SVG
* Apply version-specific overrides for net8
* Fix _serviceProvider access level for net8 branch sync
Change _serviceProvider from private to protected in BasePersistenceProvider
to match main branch. Required by TickerEFCorePersistenceProvider which
accesses it for the new ITickerQueryable methods.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Daniel Nordström <daniel.mauritzson@gmail.com>
Co-authored-by: Cédric Hulin <hulin.cedric@gmail.com>
Co-authored-by: Alex <58499431+AlexeyKhlebnikov@users.noreply.github.com>
Co-authored-by: jods <jods4@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jods4 <3832820+jods4@users.noreply.github.com>
Co-authored-by: EarlJester <111294669+EarlJester@users.noreply.github.com>
Co-authored-by: EarlJester <shon3322@gmail.com>
Co-authored-by: stevewoj <steve.wojciechowski@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Wojciech Wentland <wojciech.wentland@int.pl>
Co-authored-by: Ingmar Olmaru <48388318+Kedireng@users.noreply.github.com>
Co-authored-by: albert-miden <albert@miden.co>
Co-authored-by: Alberti's MacMini <albert@Albertis-Mac-mini.local>
Co-authored-by: Rafael Câmara <52082556+RafaelJCamara@users.noreply.github.com>
Co-authored-by: Valiantsin Leushyts <levshits.l@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #497
I have fixed the two places where timeago was called on strings possibly without a TZ offset, which results in the wrong time being displayed.
I also factored this logic into a utility method that's used consistently everywhere (no more direct usage of timeago.js with copy-pasted Z handling).
In the specific places where I edited code, I unified inconsistent
!==and!=usage for comparisons.I've also removed redundant
!= undefinedchecks: when you double-equalsnullandundefinedare the same.